From 0dbfee0eda541c8451d116ee7b1b81f10d7390cf Mon Sep 17 00:00:00 2001 From: b Date: Mon, 12 Feb 2024 22:14:10 +0000 Subject: [PATCH] keep just the old logs tool as standalone version now --- .gitmodules | 3 - 2words.1.pl | 676 ---------- attach.1.pl | 195 --- bbcode.1.pl | 165 --- botm-common | 2 +- botmlogo.png | Bin 463 -> 0 bytes bsta.1.conf | 15 - bsta.1.cron | 5 - bsta.css | 492 ------- bsta_lib.1.pm | 2934 ------------------------------------------ chat.1.pl | 507 -------- exec | 1 - frame.1.pl | 206 --- goto.1.pl | 123 -- info.1.pl | 263 ---- install.sh | 5 +- makefile | 143 +- makefile.1.mak | 139 +- oldlogs.1.pl | 5 +- ong.1.pl | 213 --- opomba.1.pl | 591 --------- reset.1.pl | 160 --- settings-again.txt | 92 -- settings-bsta.txt | 92 -- settings-debug.txt | 62 +- settings-release.txt | 36 + settings.txt | 166 +-- timer.js | 95 -- update.1.pl | 253 ---- viewer.1.pl | 384 ------ 30 files changed, 80 insertions(+), 7943 deletions(-) delete mode 100644 2words.1.pl delete mode 100644 attach.1.pl delete mode 100644 bbcode.1.pl delete mode 100644 botmlogo.png delete mode 100644 bsta.1.conf delete mode 100644 bsta.1.cron delete mode 100644 bsta.css delete mode 100644 bsta_lib.1.pm delete mode 100644 chat.1.pl delete mode 160000 exec delete mode 100644 frame.1.pl delete mode 100644 goto.1.pl delete mode 100644 info.1.pl delete mode 100644 ong.1.pl delete mode 100644 opomba.1.pl delete mode 100644 reset.1.pl delete mode 100644 settings-again.txt delete mode 100644 settings-bsta.txt create mode 100644 settings-release.txt delete mode 100644 timer.js delete mode 100644 update.1.pl delete mode 100644 viewer.1.pl diff --git a/.gitmodules b/.gitmodules index 7c416db..55b1b1e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "config"] path = config url = ../../botm/config -[submodule "exec"] - path = exec - url = ../../botm/exec [submodule "botm-common"] path = botm-common url = ../../botm/common-perl diff --git a/2words.1.pl b/2words.1.pl deleted file mode 100644 index 1bc2d74..0000000 --- a/2words.1.pl +++ /dev/null @@ -1,676 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/2words -# 2words is generated from 2words.1.pl. -# -# The wordgame interface -# -# Copyright (C) 2016, 2017, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'http_header_status', 'http_header_allow', - 'merge_url', - 'read_header_env', - 'html_entity_encode_dec', - 'url_query_decode', 'url_query_encode', - 'open_encoded' -); -use bsta_lib ( - 'STATE', 'INTF_STATE', - 'get_id', - 'fail_method', 'fail_content_type', - 'print_html_start', 'print_html_end', - 'print_html_head_start', 'print_html_head_end', - 'print_html_body_start', 'print_html_body_end', - 'write_index', - 'get_remote_addr', 'get_password', - 'merge_settings', - 'ong', - 'read_story', 'write_story', - 'read_settings', 'read_state' -); - -###PERL_CGI_PATH: CGI_PATH = /bsta/ -###PERL_CGI_2WORDS_PATH: CGI_2WORDS_PATH = /bsta/2words - -###PERL_DATA_STORY_PATH: DATA_STORY_PATH = /botm/data/bsta/story - -###PERL_WEBSITE_NAME: WEBSITE_NAME = Bicycles on the Moon - -###PERL_STORY_LENGTH: STORY_LENGTH = 16 -###PERL_PAGE_LENGTH: PAGE_LENGTH = 16 -###PERL_FIRSTPAGE_LENGTH: FIRSTPAGE_LENGTH = 4 - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my %http; -my %cgi; -my %story; -my %new_story; -my %settings; -my %state; - -my $time = time(); -srand ($time-$$); - -my $method; -my $IP; -my $words; -my $color2; -my $last_IP; -my $story_id; -my $turn; -my $status; -my $allow; -my $message; -my $first_letter; -my $second_letter; -my $last_letter; -my $intf_state; -my $intf_pass; -my $intf_pause; -my $intf_mode; -my $fh; -my $story_lock; -my @story_lines; -my $ong_state; -my $page; -my $password; -my $password_ok; - - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else { - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET','POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else{ - exit fail_content_type($method, $http{'content-type'}); - } -} - -$IP = get_remote_addr(); -$page = get_id(\%cgi); -$password = get_password(\%cgi); -if ($cgi{'words'} ne '') { - $words = $cgi{'words'}; -} - -%settings = read_settings(); -%state = read_state(); -$ong_state = int($state{'state'}); - -$password_ok = ($password eq $settings{'password'}); -if ($password_ok) { - $IP .= ' OK'; -} - -$story_lock=0; -if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { - $story_lock=1; - if (flock($fh,2)) { - $story_lock=2; - } - %story = read_story($fh); - - if ($story{'lastip'} =~ /^.+$/) { - $last_IP=$&; - } - else { - $last_IP='0.0.0.0'; - } - - $last_letter = lc($story{'letter'}); - $story_id = int($story{'id'}); - $intf_pass = int($story{'pass'}); - $intf_state = int($story{'state'}); - $intf_mode = $intf_state & INTF_STATE->{'mode'}; - $intf_pause = $intf_state & INTF_STATE->{'||'}; - - if ($IP ne $last_IP) { - $turn = 1; - } - else { - $turn = 0; - } - - if ( - ($intf_state < 0) || ( - ($method eq 'POST') && ( - ($cgi{'clear'} ne '') || - ($cgi{'clear_all'} ne '') - ) - ) - ) { - if ( - ($cgi{'clear_all'} ne '') || - ($intf_state < -1) - ) { - $story{'id'} = 0; - } - $story{'content'} = ''; - $story{'lastip' } = '0.0.0.0'; - $story{'letter' } = ''; - $story{'pass' } = 0; - $story{'state' } = INTF_STATE->{'X'}; - $turn = 0; - if ($ong_state == STATE->{'inactive'}) { - write_index( - \%state, - \%settings, - $story{'pass'}, - $story{'state'}, - 0 # pause - ); - } - write_story($fh, \%story); - } - - if (($words ne '') && ($method eq 'POST')) { - if ( - (!$turn) && - (!$password_ok) - ) { - $status = HTTP_STATUS->{'forbidden'}; - $message = "It's not your turn."; - } - # TODO: consider allowing non-ASCII letters in words. - # (not very important in English language) - elsif ( - ($words =~ /^([!"\(\),\.:;\?][ \t]*)?([A-Za-z][A-Za-z'\-]*[A-Za-z']?)([!"\(\),\.:;\? \t][ \t]*)([A-Za-z][A-Za-z'\-]*[A-Za-z']?)([!"\(\),\.:;\?]?[ \t]*)$/) || - ($password_ok && ($words ne '')) - ) { - # we have 2 words - $first_letter = lc(substr($2, 0, 1)); - $second_letter = lc(substr($4, 0, 1)); - if ( - ($first_letter ne $last_letter) && - ($last_letter ne '') && - (!$password_ok) - ) { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'The first word must start with '.uc($last_letter).'.'; - } - elsif ( - ($first_letter eq $second_letter) && - (!$password_ok) - ) { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'The second word can\'t also start with '.uc($first_letter).'.'; - } - else { - # words are valid - # update state - $story{'content'} = $story{'content'} . $words."\n"; - $turn = 0; - $story{'lastip'} = $IP; - $story{'letter'} = $second_letter; - - if ($cgi{'next'} ne '') { - # start next game - if ( - $password_ok || - (split(/\r?\n/,$story{'content'}) >= (STORY_LENGTH-1)) - ) { - # store finished game - write_story($story_id, \%story); - # init new game - $new_story{'id' } = $story_id + 1; - $new_story{'letter' } = ''; - $new_story{'lastip' } = $IP; - $new_story{'content'} = ''; - $new_story{'pass' } = 0; - $new_story{'state' } = INTF_STATE->{'X'}; - # reset hidden interface - $intf_state = INTF_STATE->{'X'}; - $intf_pass = 0; - $intf_mode = INTF_STATE->{'X'}; - $intf_pause= 0; - if($ong_state == STATE->{'inactive'}) { - # ONG not activated yet; reset index - write_index( - \%state, - \%settings, - $intf_pass, - $intf_mode, - $intf_pause - ); - } - # save new game - write_story($fh, \%new_story); - } - else { - $message = 'To early to finish this wordgame.'; - write_story($fh, \%story); - } - } - else { - # continue the game - if ($intf_pass == 1) { - # hidden interface was already active; deactivate - $intf_pass = 2; - $story{'pass'} = 2; - if($ong_state == STATE->{'inactive'}) { - write_index( - \%state, - \%settings, - $intf_pass, - $intf_mode, - $intf_pause - ); - } - } - elsif(lc($2).' '.lc($4) eq $settings{'unlock'}) { - # correct password for the hidden interface! - if ($intf_pass != 0) { - $message = 'The password has already been used in this story.'; - } - elsif ($ong_state != STATE->{'inactive'}) { - # ONG already active, nothing to do here - $message = "???"; - } - else { - # ready to activate? - my $r; - - # ONG tape interface - $r = ong( - 'i', # ID: tape interface - $time, # ONG time; not relevant - 0, # timer; not relevant - 0, # update; not relevant - 0, # print - \%settings, # not relevant - '', # %default; not relevant - '', # %frame_data; not relevant - '' # $goto_list; not relevant - ); - if ($r) { - # ONG CFRT - $r = ong( - 'c', # ID: CFRT - $time, # ONG time; not relevant - 0, # timer; not relevant - 0, # update; not relevant - 0, # print - \%settings, - '', # %default - '', # %frame_data - '' # $goto_list; not relevant - ); - } - if ($r) { - # ONG frame 0! - $r = ong( - 0, # frame ID - $time, # ONG time; might get overwritten later - 0, # timer - 0, # update - 0, # print - \%settings, - '', # %default - '', # %frame_data - '' # $goto_list - ); - } - if($r) { - # new state of hidden interface - $intf_pass = 1; - $intf_state = INTF_STATE->{'X'}; - $intf_mode = INTF_STATE->{'X'}; - $intf_pause = 0; - $story{'pass'} = 1; - $story{'state'} = INTF_STATE->{'X'}; - write_index( - \%state, - \%settings, - $intf_pass, - $intf_mode, - $intf_pause - ); - } - } - } - write_story($fh, \%story); - } - } - } - else { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Please, two words, not more, not less (some punctuation is allowed).'; - } - } - elsif ( - ($cgi{'s'} ne '') && - ($intf_pass == 1) && - ($ong_state == STATE->{'inactive'}) - ) { - $intf_state = int($cgi{'s'}) & INTF_STATE->{'mask'}; - $intf_mode = $intf_state & INTF_STATE->{'mode'}; - $intf_pause = $intf_state & INTF_STATE->{'||'}; - $story{'state'} = $intf_state; - write_index( - \%state, - \%settings, - $intf_pass, - $intf_mode, - $intf_pause - ); - write_story($fh, \%story); - } - @story_lines = split(/\r?\n/, $story{'content'}); - if(@story_lines & 1) { - $turn = !$turn; - } - - close($fh); -} - -if ($status ne '') { - print http_header_status($status); -} -if ($allow ne '') { - print http_header_allow($allow); -} -print "Content-type: text/html; charset=UTF-8\n\n"; - -if($method eq 'HEAD') { - exit; -} - -my $max_page = int(($story_id + PAGE_LENGTH - FIRSTPAGE_LENGTH - 1) / PAGE_LENGTH); -my $newer_available = ($page > 0); -my $older_available = ($page < $max_page); -my $show_intf = ($intf_pass == 1) && ($ong_state == STATE->{'inactive'}); -my $id_start = - $story_id-1 -( - ($page == 0) ? 0 : ( - (($page-1) * PAGE_LENGTH ) + FIRSTPAGE_LENGTH - ) - ); -my $id_stop = $story_id-1 - (($page*PAGE_LENGTH) + FIRSTPAGE_LENGTH); -if ($id_stop < 0) { - $id_stop = -1; -} - -my $bsta_url = CGI_PATH; -my $twowords_url = CGI_2WORDS_PATH; -my $newer_url; -my $older_url; -my $oldest_url; -my $newest_url = merge_url( - {'path' => $twowords_url}, - {'path' => 0} -); -if ($newer_available) { - $newer_url = merge_url( - {'path' => $twowords_url}, - {'path' => $page-1} - ); -} -if ($older_available) { - $older_url = merge_url( - {'path' => $twowords_url}, - {'path' => $page+1} - ); - $oldest_url = merge_url( - {'path' => $twowords_url}, - {'path' => $max_page} - ); -} -my $button_4_url = merge_url( - {'path' => $twowords_url}, - {'query' => {'s' => (INTF_STATE->{'>'} | $intf_pause)}} -); -my $button_3_url = merge_url( - {'path' => $twowords_url}, - {'query' => {'s' => (INTF_STATE->{'<<'} | $intf_pause)}} -); -my $button_2_url = merge_url( - {'path' => $twowords_url}, - {'query' => {'s' => (INTF_STATE->{'>>'} | $intf_pause)}} -); -my $button_1_url = merge_url( - {'path' => $twowords_url}, - {'query' => {'s' => INTF_STATE->{'X'}}} -); -my $button_0_url = merge_url( - {'path' => $twowords_url}, - {'query' => {'s' => ($intf_pause ? $intf_mode : ($intf_mode | INTF_STATE->{'||'}))}} -); -my $button_5_img = merge_url( - {'path' => CGI_PATH()}, - {'path' => 'intf-20.gif'} -); -my $button_4_img = merge_url( - {'path' => CGI_PATH()}, - {'path' => 'intf-10'.(($intf_mode == INTF_STATE->{'>'}) ? '_' : '').'.gif'} -); -my $button_3_img = merge_url( - {'path' => CGI_PATH()}, - {'path' => 'intf-08'.(($intf_mode == INTF_STATE->{'<<'}) ? '_' : '').'.gif'} -); -my $button_2_img = merge_url( - {'path' => CGI_PATH()}, - {'path' => 'intf-04'.(($intf_mode == INTF_STATE->{'>>'}) ? '_' : '').'.gif'} -); -my $button_1_img = merge_url( - {'path' => CGI_PATH()}, - {'path' => 'intf-02.gif'} -); -my $button_0_img = merge_url( - {'path' => CGI_PATH()}, - {'path' => 'intf-01'.($intf_pause ? '_' : '').'.gif'} -); -my $intf_img_id = ''; -if ($intf_state == INTF_STATE->{'>'}) { - $intf_img_id = '_10' -} -elsif ($intf_mode == INTF_STATE->{'<<'}) { - $intf_img_id = '_08' -} -elsif ($intf_mode == INTF_STATE->{'>>'}) { - $intf_img_id = '_04' -} -my $intf_img = merge_url( - {'path' => CGI_PATH()}, - {'path' => 'intf-00'.$intf_img_id.'.gif'} -); - -if ($password_ok) { - my $password_query = url_query_encode({'p', $settings{'password'}}); - $twowords_url = merge_url($twowords_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $newest_url = merge_url($newest_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $newer_url = merge_url($newer_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $older_url = merge_url($older_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $button_4_url = merge_url($button_4_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $button_3_url = merge_url($button_3_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $button_2_url = merge_url($button_2_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $button_1_url = merge_url($button_1_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $button_0_url = merge_url($button_0_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); -} - -my $_password = $password_ok ? html_entity_encode_dec($settings{'password'}, 1): ''; -my $_bsta_url = html_entity_encode_dec($bsta_url , 1); -my $_twowords_url = html_entity_encode_dec($twowords_url , 1); -my $_newest_url = html_entity_encode_dec($newest_url , 1); -my $_newer_url = html_entity_encode_dec($newer_url , 1); -my $_older_url = html_entity_encode_dec($older_url , 1); -my $_oldest_url = html_entity_encode_dec($oldest_url , 1); -my $_button_4_url = html_entity_encode_dec($button_4_url , 1); -my $_button_3_url = html_entity_encode_dec($button_3_url , 1); -my $_button_2_url = html_entity_encode_dec($button_2_url , 1); -my $_button_1_url = html_entity_encode_dec($button_1_url , 1); -my $_button_0_url = html_entity_encode_dec($button_0_url , 1); -my $_button_5_img = html_entity_encode_dec($button_5_img , 1); -my $_button_4_img = html_entity_encode_dec($button_4_img , 1); -my $_button_3_img = html_entity_encode_dec($button_3_img , 1); -my $_button_2_img = html_entity_encode_dec($button_2_img , 1); -my $_button_1_img = html_entity_encode_dec($button_1_img , 1); -my $_button_0_img = html_entity_encode_dec($button_0_img , 1); -my $_intf_img = html_entity_encode_dec($intf_img , 1); -my $_message = html_entity_encode_dec($message , 1); -my $_website_name = html_entity_encode_dec(WEBSITE_NAME(), 1); - -print_html_start(\*STDOUT); -print_html_head_start(\*STDOUT); - - -print ' Two words • '.$_website_name.''."\n"; -print ' '."\n"; -if ($older_available) { - print ' '."\n"; -} -if ($newer_available) { - print ' '."\n"; -} - -print_html_head_end(\*STDOUT); -print_html_body_start(\*STDOUT); - -print '
'."\n"; - -print '
'."\n"; -print '

Two words

'."\n"; -print '
'."\n"; - -if ($page == 0) { - print '
'."\n"; - for (my $i = 0; $i < @story_lines; ++$i) { - print ' '.html_entity_encode_dec($story_lines[$i], 1).''."\n"; - $turn = !$turn; - } - print '
'."\n"; - - print '
'."\n"; - if ($message ne '') { - print ' '.$_message.''."\n"; - } - - if ($turn || $password_ok) { - print '
'."\n"; - if ($message eq '') { - if ($story{"content"} eq '') { - print ' Two words, please:
'."\n"; - } - else { - print ' Please continue, two words:
'."\n"; - } - } - print ' '."\n"; - print ' '."\n"; - if ((@story_lines >= (STORY_LENGTH-1)) || $password_ok ) { - print ' '."\n"; - } - if ($password_ok) { - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - } - print '
'."\n"; - } - else { - if ($message eq '') { - print ' Wait for it.'."\n"; - } - } - print '
'."\n"; -} -elsif ($message ne '') { - print '
'."\n"; - print ' '.$_message.''."\n"; - print '
'."\n"; -} -print '
'."\n"; - -if ($show_intf) { - print '
'."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print '
o><<>>^||
'."\n"; - print '
'."\n"; -} - -print '
'."\n"; - -print '
'."\n"; -for (my $i = $id_start; $i > $id_stop; --$i) { - %new_story = read_story($i); - print '

'.html_entity_encode_dec($new_story{'content'}).'

'."\n"; -} -print '
'."\n"; - -print ' '."\n"; - -print '
'."\n"; - -print_html_body_end(\*STDOUT, $ong_state == STATE->{'inactive'}); -print_html_end(\*STDOUT); diff --git a/attach.1.pl b/attach.1.pl deleted file mode 100644 index cb34f63..0000000 --- a/attach.1.pl +++ /dev/null @@ -1,195 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/a -# attach.pl is generated from attach.1.pl. -# -# The attachment interface -# -# Copyright (C) 2016, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'read_header_env', - 'url_query_decode', - 'join_path', - 'merge_url', - 'open_encoded', 'stat_encoded', - 'http_header_line', 'http_header_content_length', 'http_header_content_disposition' -); -use bsta_lib ( - 'STATE', - 'merge_settings', - 'get_id', 'get_password', - 'fail_method', 'fail_content_type', 'fail_attachment', 'fail_500', - 'redirect', - 'read_settings', 'read_state', 'read_attachment' -); - -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_CGI_PATH: CGI_PATH = /bsta/ -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta -###PERL_WWW_PATH: WWW_PATH = /botm/www/1190/bsta/ - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my $time = time(); -srand ($time-$$); - -my %http; -my %cgi; -my %settings; -my %state; -my %file_data; - -my $method; -my $ID; -my $frame; -my $last_frame; -my $ong_state; -my $password; -my $password_ok; -my $IP; -my $try_onged; -my $buffer; -my $fh; -my $file_path; -my $file_name; -my $direct; -my $r = 0; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else{ - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else{ - exit fail_content_type($method, $http{'content-type'}); - } -} - -$ID = get_id( \%cgi); -$password = get_password(\%cgi); - -%settings = read_settings(); -%state = read_state(); -%file_data = read_attachment($ID); -$frame = ($file_data{'frame'} ne '') ? int($file_data{'frame'}) : -1; -$last_frame = int($state{'last'}); -$ong_state = int($state{'state'}); -$file_name = $file_data{'filename'}; - -$password_ok = ($password eq $settings{'password'}); - -unless ( - ($file_name ne '') && ( - $password_ok || ( - ($ong_state >= STATE->{'waiting'}) && - ($frame <= $last_frame) && - ($frame >=0) - ) - ) -) { - exit fail_attachment($method, $ID); -} - -if ($file_data{'content'} ne '') { - $direct = 1; -} -else { - $direct = 0; - $try_onged = ( - ($ong_state >= STATE->{'waiting'}) && - ($frame <= $last_frame) && - ($frame >=0) - ); - if ($try_onged) { - $file_path = join_path(PATH_SEPARATOR(), WWW_PATH(), $file_name); - $r = open_encoded($fh, '<' , $file_path); - if ($r) { - close($r); - $file_path = merge_url( - {'path' => CGI_PATH()}, - {'path' => $file_name} - ); - exit redirect ($method, $file_path, HTTP_STATUS->{'see_other'}); - } - } - unless ($r) { - $file_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $file_name); - $r = open_encoded($fh,'<', $file_path); - unless ($r) { - exit fail_attachment($method, $ID); - } - } - unless (binmode($fh)) { - close($fh); - exit fail_500("Can't switch file to binary mode."); - } - if (my @file_info = stat_encoded($file_path)) { - print http_header_content_length($file_info[7]); - } -} -if ($file_data{'content-type'} ne '') { - print http_header_line('content-type', $file_data{'content-type'}); -} -if ($file_name ne '') { - print http_header_content_disposition('inline', $file_name); -} -unless ($direct) { - unless (binmode STDOUT) { - close($fh); - exit fail_500("Can't switch output to binary mode."); - } -} -print "\n"; - -if($method ne 'HEAD'){ - if($direct) { - print $file_data{'content'}; - } - else { - while (read ($fh, $buffer, 1024)) { - print (STDOUT $buffer); - } - } -} -unless ($direct) { - close($fh); -} diff --git a/bbcode.1.pl b/bbcode.1.pl deleted file mode 100644 index 28e5e6d..0000000 --- a/bbcode.1.pl +++ /dev/null @@ -1,165 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/b -# bbcode.pl is generated from bbcode.1.pl. -# -# The bbcode interface -# -# Copyright (C) 2017, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'read_header_env', - 'url_query_decode', - 'merge_url', - 'http_header_status' -); -use bsta_lib ( - 'STATE', - 'fail_method', 'fail_content_type', - 'get_frame', 'get_password', - 'merge_settings', - 'eval_bb', 'bb_to_bbcode', - 'get_frame_file', - 'read_frame_data', 'read_default', 'read_noaccess', - 'read_settings', 'read_state' -); - -###PERL_CGI_PATH: CGI_PATH = /bsta/ -###PERL_CGI_VIEWER_PATH: CGI_VIEWER_PATH = /bsta/v - -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta/ - -###PERL_SCHEME: SCHEME = http -###PERL_WEBSITE: WEBSITE = 1190.bicyclesonthemoon.info - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my $time = time(); -srand ($time-$$); - -my %http; -my %cgi; -my %frame_data; -my %default; -my %settings; -my %state; - -my $method; -my $frame; -my $password; -my $password_ok; -my $access; -my $ongtime; -my $ong_state; -my $last_frame; -my $frame_data_path; -my $frame_file; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else{ - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else{ - exit fail_content_type($method, $http{'content-type'}); - } -} - -$frame = get_frame(\%cgi); -$password = get_password(\%cgi); - -%settings = read_settings(); -%default = read_default(); -%state = read_state(); - -$ong_state = int($state{'state'}); -$last_frame = int($state{'last'}); - -$password_ok = ($password eq $settings{'password'}); - -if ($frame < 0) { - $frame = $last_frame + $frame +1; -} -%frame_data = read_frame_data($frame, \%default); - -if ( - $password_ok || ( - ($ong_state >= STATE->{'waiting'}) && - ($frame <= $last_frame) && - ($frame >= 0) - ) -) { - $access = 1; -} -else { - $access=0; - %frame_data = read_noaccess(\%default); -} -$frame_file = get_frame_file($frame, \%frame_data, \%settings); - -print "Content-type: text/plain; charset=UTF-8\n"; -if(!$access) { - print http_header_status(HTTP_STATUS->{'forbidden'}); -} -print "\n"; -if($method eq 'HEAD') { - exit; -} - -my $viewer_url = merge_url( - {'scheme' => SCHEME(), 'host' => WEBSITE()}, - {'path' => CGI_VIEWER_PATH()}, - {'path' => $frame} -); -my $frame_url = merge_url( - {'scheme' => SCHEME(), 'host' => WEBSITE()}, - {'path' => CGI_PATH()}, - {'path' => $frame_file} -); -my $content = bb_to_bbcode( - eval_bb( - $frame_data{'content'}, - 1 - ) -); - -print '[quote][center][size=200]'.$frame_data{'title'}.'[/size]'."\n"; -print '[url='.$viewer_url.'][img]'.$frame_url.'[/img][/url][/center]'."\n"; -print $content.'[/quote]'."\n"; diff --git a/botm-common b/botm-common index 54a9ab5..44fbe59 160000 --- a/botm-common +++ b/botm-common @@ -1 +1 @@ -Subproject commit 54a9ab5889510496f8820da830f46068703aa8d6 +Subproject commit 44fbe59bfd7652a0975e601591df4a4b218da40d diff --git a/botmlogo.png b/botmlogo.png deleted file mode 100644 index d4aea7fe74ea08e47926652002f215fa7e17896f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 463 zcmV;=0WkiFP)DarOnQmFRKh4K!}f|>z=Q)L`9QuMY|LLz!K=JkhyRvr4YsJwfxY5 zagWx1#;5GPqsfkMhmWm)JLl{U<6rTde-Li~Si`UN#d=?KPqbt%T+8Hj`+KNdZ;Z}F zg}gZgo0oGJ-;b;^LfHV=rEFeg&PHxor?wMSx3hM7*V3Bb?U<}Q#;Tw3UF%P^zh9sB z_aAAt)_&H$HRh;)%&g1}HT9XZ_MY~y zx5*rK3DDS5C2g(M( zU6n0*j^Np46qM=_iIP1zjpd)ET&? - Require all granted - diff --git a/bsta.1.cron b/bsta.1.cron deleted file mode 100644 index 96c38df..0000000 --- a/bsta.1.cron +++ /dev/null @@ -1,5 +0,0 @@ -# bsta.cron is automatically generated from bsta.1.cron - -###CRON_OLDLOGS_SCHEDULE; ###CRON_USER; ###CRON_OLDLOGS; ###CRON_LOG; ###CRON_LOG_SIZE_LIMIT; ###CRON_LOGS_TOTAL; ###CRON_LOGS_UNCOMPRESSED; -###CRON_ONG_SCHEDULE; ###CRON_USER; ###CRON_ONG; >> ###CRON_ONG_LOG; -###CRON_RESET_SCHEDULE; ###CRON_USER; ###CRON_RESET; ###CRON_RESET_PASSWORD; diff --git a/bsta.css b/bsta.css deleted file mode 100644 index da52470..0000000 --- a/bsta.css +++ /dev/null @@ -1,492 +0,0 @@ -html -{ - background-color: #46a3ff; - /* background-color: #d9ecff; */ - border-color: #000000; - color: #000000; - text-align: center; -} - -a -{ - border-color: #0057af; - color: #0057af; - text-decoration:underline; -} -a:visited -{ - border-color: #bb6622; - color: #bb6622; -} -a:hover -{ - border-color: #bb6622; - color: #bb6622; -} -a:hover:visited -{ - border-color: #0057af; - color: #0057af; -} -::selection -{ - color: #ffffff; - background-color: #bb6622; -} - -div#all -{ - background-color: #d9ecff; - /* background-color: #ffffff; */ - margin-left: auto; - margin-right: auto; - margin-top: 0px; - margin-bottom: 0px; - width: 656px; - padding-top: 27px; - padding-bottom: 27px; - text-align: center; -} -div.all -{ - background-color: #d9ecff; - /* background-color: #ffffff; */ - margin-left: auto; - margin-right: auto; - margin-top: 0px; - margin-bottom: 0px; - width: 656px; - padding-top: 27px; - padding-bottom: 27px; - text-align: center; -} - -div.ins -{ - background-color: #ffffff; - margin-left: auto; - margin-right: auto; - margin-top: 0px; - margin-bottom: 0px; - padding: 0px; - border: 0px; - width: 580px; -} -div#inst -{ - /* margin-top: 27px; */ - /* margin-bottom: 0px; */ -} -div#insb -{ - /* margin-top: 0px; */ - /* margin-bottom: 27px; */ -} - -div#title -{ - text-align: center; - padding-top: 21px; - padding-bottom: 21px; - padding-left: 0px; - padding-right: 0px; - border: 0px; - margin: 0px; -} -div.title -{ - text-align: center; - padding-top: 21px; - padding-bottom: 21px; - padding-left: 0px; - padding-right: 0px; - border: 0px; - margin: 0px; -} - -h1#titletext -{ - margin: 0px; - border: 0px; - padding: 0px; -} -h1.titletext -{ - margin: 0px; - border: 0px; - padding: 0px; -} - -div#storypuzzle -{ - text-align: left; - padding: 8px; - margin: 0px; - border: 0px; - font-weight: bold; -} - -div#framespace -{ - background-color: #ffffff; - margin-left: auto; - margin-right: auto; - margin-top: 0px; - margin-bottom: 0px; - padding: 0px; - border: 0px; - width: 656px; -} - -img#frame -{ - border: solid #0057af; - border-width: 27px 38px; - padding: 0px; - margin: 0px; -} -img#frame:hover -{ - border-color: #bb6622; -} -img#frame.double -{ - border-width: 54px 38px; -} -img#frame.full -{ - border-width: 0px; - background-color: #0057af; -} -img#frame.full#hover -{ - background-color: #bb6622; -} -img#frame.bftf -{ - padding-top: 60px; - padding-bottom: 60px; - padding-left: 85px; - padding-right: 85px; - background-color: #d9ecff; -} - -img.intf -{ - border-width: 0px; - padding: 0px; - margin: 0px; -} -tr.intf -{ - border-width: 0px; - padding: 0px; - margin: 0px; -} -td.intf -{ - border-width: 0px; - padding: 0px; - margin: 0px; -} -table#intftable -{ - border: solid #0057af; - border-width:27px 38px; - padding: 0px; - margin: 0px; - background-color: #ffffff; - border-collapse: collapse; - border-spacing: 0px; -} - -div#undertext -{ - text-align: left; - padding: 8px; - margin: 0px; - border: 0px; -} -div.undertext -{ - text-align: left; - padding: 8px; - margin: 0px; - border: 0px; -} - -div#chat -{ - text-align: left; - padding: 8px; - margin: 0px; - border: 0px; - font-family: monospace; -} - -div.fq -{ - text-align: left; - border: solid #0057af 4px; - font-family: monospace; - padding: 2px; -} -div.fq:hover -{ - border-color: #bb6622; -} -div.tq -{ - text-align: left; - border: solid #0057af 4px; - padding: 2px; -} -div.tq:hover -{ - border-color: #bb6622; -} - -div.opomba -{ - text-align: left; - border: solid #0057af 4px; - background-color: #0057af; -} -div.opomba:hover -{ - border-color: #bb6622; - background-color: #bb6622; -} -div.opomba:target -{ - border-color: #bb6622; - background-color: #bb6622; -} -div.opomba:target:hover -{ - border-color: #bb6622; - background-color: #bb6622; -} -div.opomba_info -{ - color: #ffffff!important; - /* font-weight: bold; */ -} -div.opomba_text -{ - background-color: #ffffff; - color: #000000; - clear: both; - padding: 4px; -} - -div.space -{ - background-color: #46a3ff; - height: 27px; - margin-top: 27px; - margin-bottom: 27px; -} - -div#command -{ - text-align: left; - margin: 0px; - border: 0px; - padding: 8px; - font-family: monospace; - font-size: 150%; - /* font-weight: bold; */ -} - -div#underlinks -{ - text-align: left; - padding: 8px; - margin: 0px; - border: 0px; - font-family: monospace; -} -div.underlinks -{ - text-align: left; - padding: 8px; - margin: 0px; - border: 0px; - font-family: monospace; -} - -span.inp -{ - animation: inp 2380ms step-start infinite; -} -@keyframes inp -{ - 50% { opacity: 0.0;} -} - -input.intx -{ - border-color: #0057af; - color: #000000; - background-color: #ffffff; - border-width: 2px; - border-style: solid; - margin: 2px; - font-family: monospace; - /* font-size: 150%; */ -} -input.intx:focus -{ - border-color: #bb6622; -} -input.intx:hover -{ - border-color: #bb6622; -} - -input.intxc -{ - border-color: #0057af; - color: #000000; - background-color: #ffffff; - border-width: 2px; - border-style: solid; - margin: 2px; - font-family: monospace; - width: 100%; - /* font-size: 150%; */ -} -input.intxc:focus -{ - border-color: #bb6622; -} -input.intxc:hover -{ - border-color: #bb6622; -} - -/* table.intxc -{ - width=100%; -} */ - -textarea.inta -{ - border-color: #0057af; - color: #000000; - background-color: #ffffff; - border-width: 2px; - border-style: solid; - width: 100%; - margin: 2px; - resize: none; -} -textarea.inta:focus -{ - border-color: #bb6622; -} -textarea.inta:hover -{ - border-color: #bb6622; -} - -input.inbt -{ - border-color: #0057af; - color: #000000; - background-color: #ffffff; - border-width: 2px; - border-style: solid; - margin: 2px; - font-family: monospace; - /* font-size: 150%; */ -} -input.inbt:focus -{ - border-color: #bb6622; -} -input.inbt:hover -{ - border-color: #bb6622; -} - -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; - color: #0057af; -} -input.hl:hover { - border-color: #bb6622; - color: #bb6622; -} -form.hl { - display: inline -} - -form.goto { - clear: both; - display: inline -} - -.br -{ - border-color: #bb6622!important; - color: #bb6622!important; -} -.po -{ - border-color: #ff8800!important; - color: #ff8800!important; -} -.ni -{ - border-color: #0057af!important; - color: #0057af!important; -} -.bi -{ - border-color: #ffffff!important; - color: #ffffff!important; -} -.cz -{ - border-color: #000000!important; - color: #000000!important; -} - -.hv.ni:hover -{ - border-color: #bb6622!important; - color: #bb6622!important; -} - -.hv.br:hover -{ - border-color: #0057af!important; - color: #0057af!important; -} - -.hu -{ - text-decoration:none!important; -} -.hu:hover -{ - text-decoration:underline!important; -} - -div.le -{ - float: left; -} -div.pr -{ - float: right; -} diff --git a/bsta_lib.1.pm b/bsta_lib.1.pm deleted file mode 100644 index 7545a90..0000000 --- a/bsta_lib.1.pm +++ /dev/null @@ -1,2934 +0,0 @@ -# bsta_lib.pm is generated from bsta_lib.1.pm -# -# Library of functions -# -# Copyright (C) 2016, 2017, 2019, 2020, 2022, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -# TODO: FQ NBSP ? -# TODO: DEBUG -# TODO: BB & INFO indent - -package bsta_lib; - -use strict; -#use warnings - -use utf8; -use Encode ('encode', 'decode'); -use Exporter; -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); - -###PERL_EXPORT_VERSION: our $VERSION = 'x.x.x'; -our @ISA = qw(Exporter); -our @EXPORT = (); -our @EXPORT_OK = ( - 'STATE', 'TEXT_MODE', 'INTF_STATE', 'CHAT_STATE', 'CHAT_ACTION', - 'failpage', - 'fail_method', 'fail_content_type', 'fail_open_file', 'fail_attachment', 'fail_500', - 'redirect', - 'get_remote_addr', 'get_id', 'get_frame', 'get_password', - 'merge_settings', - 'print_html_start', 'print_html_end', - 'print_html_head_start', 'print_html_head_end', - 'print_html_body_start', 'print_html_body_end', - 'print_viewer_page', 'print_goto', - 'write_index', 'write_static_viewer_page', 'write_static_goto', - 'get_frame_file', 'get_page_file', - 'read_frame_data', 'write_frame_data', 'read_default', 'read_noaccess', - 'read_state', 'write_state', - 'read_words_list', 'write_words_list', 'read_words', 'write_words', - 'read_story', 'write_story', - 'read_goto', 'write_goto', - 'read_chat', 'write_chat', - 'read_settings', 'read_attachment', 'read_coincidence', - 'ong', - 'eval_bb', 'bb_to_bbcode', 'bb_to_html' -); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'url_query_decode', 'url_query_encode', - 'url_decode', 'url_encode', - 'html_entity_encode_dec', - 'merge_url', - 'read_header_env', - 'read_data_file', 'write_data_file', - 'join_path', - 'copy_encoded', 'open_encoded', '_x_encoded', - 'http_header_line', 'http_status', - 'http_header_status', 'http_header_allow', 'http_header_location' -); - -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_CGI_PATH: CGI_PATH = /bsta/ -###PERL_CGI_ATTACH_PATH: CGI_ATTACH_PATH = /bsta/a -###PERL_CGI_2WORDS_PATH: CGI_2WORDS_PATH = /bsta/2words -###PERL_CGI_BBCODE_PATH: CGI_BBCODE_PATH = /bsta/b -###PERL_DATA_CHAT_PATH: DATA_CHAT_PATH = /botm/data/bsta/chat -###PERL_CGI_COIN_PATH: CGI_COIN_PATH = /bsta/coin -###PERL_CGI_CSS_PATH: CGI_CSS_PATH = /bsta/bsta.css -###PERL_CGI_FRAME_PATH: CGI_FRAME_PATH = /bsta/f -###PERL_CGI_GOTO_PATH: CGI_GOTO_PATH = /bsta/g -###PERL_CGI_INFO_PATH: CGI_INFO_PATH = /bsta/i -###PERL_CGI_LIST_PATH: CGI_LIST_PATH = /bsta/goto.htm -###PERL_CGI_LOGO_PATH: CGI_LOGO_PATH = /bsta/botmlogo.png -###PERL_CGI_TIMER_PATH: CGI_TIMER_PATH = /bsta/timer.js -###PERL_CGI_VIEWER_PATH: CGI_VIEWER_PATH = /bsta/v -###PERL_CGI_WORDS_PATH: CGI_WORDS_PATH = /bsta/w - -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta/ -###PERL_DATA_ATTACH_PATH: DATA_ATTACH_PATH = /botm/data/bsta/a -###PERL_DATA_COIN_PATH: DATA_COIN_PATH = /botm/data/bsta/coincidence -###PERL_DATA_DEFAULT_PATH: DATA_DEFAULT_PATH = /botm/data/bsta/default -###PERL_DATA_LIST_PATH: DATA_LIST_PATH = /botm/data/bsta/list -###PERL_DATA_NOACCESS_PATH: DATA_NOACCESS_PATH = /botm/data/bsta/noaccess -###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state -###PERL_DATA_STORY_PATH: DATA_STORY_PATH = /botm/data/bsta/story -###PERL_DATA_WORDS_PATH: DATA_WORDS_PATH = /botm/data/bsta/words/ - -###PERL_WWW_PATH: WWW_PATH = /botm/www/ -###PERL_WWW_GOTO_PATH: WWW_GOTO_PATH = /botm/www/1190/bsta/goto.htm -###PERL_WWW_INDEX_PATH: WWW_INDEX_PATH = /botm/www/1190/bsta/index.htm - -###PERL_SCHEME: SCHEME = http -###PERL_WEBSITE: WEBSITE = 1190.bicyclesonthemoon.info -###PERL_WEBSITE_NAME: WEBSITE_NAME = Bicycles on the Moon -###PERL_FAVICON_PATH: FAVICON_PATH = /img/favicon.png - -###PERL_COIN_DATE: COIN_DATE = 13-Nov-2016 22:15 -###PERL_INTF_DATE: INTF_DATE = 28-Sep-2016 20:34 - -###PERL_STORY_CREDITS: STORY_CREDITS = "BSTA" by Balthasar Szczepański -###PERL_INTF_CREDITS: INTF_CREDITS = Online interface © Balthasar Szczepański; AGPL 3 license -###PERL_SOURCE_URL: SOURCE_URL = http://bicyclesonthemoon.info/git-projects/?p=ott/bsta - -###PERL_COMMENT_PAGE_LENGTH:COMMENT_PAGE_LENGTH= 16 - -use constant STATE => { - 'inactive' => 0, - 'waiting' => 1, - 'ready' => 2, - 'end' => 3, -}; -use constant INTF_STATE => { - 'X' => 0b000000, - 'x' => 0b000000, - '||' => 0b000001, - '>>' => 0b000100, - '>>|'=> 0b000101, - '<<' => 0b001000, - '|<<'=> 0b001001, - '>' => 0b010000, - '>|' => 0b010001, - 'mask'=>0b111111, - 'mode'=>0b111110, -}; -use constant TEXT_MODE => { - 'normal' => 0, - 'bb' => 1, - 'info' => 2, - 'words' => 3 -}; -use constant CHAT_STATE => { - 'disconnected' => 0, - 'ready' => 1, - 'active' => 2, -}; -use constant CHAT_ACTION => { - 'none' => 0, - 'join' => 1, - 'leave' => 2, - 'nopost' => 3, - 'file' => 4, -}; - -use constant tags_bbcode => { - 'ht' => '', - '/ht' => '', - 'fq' => '[quote]', - '/fq' => '[/quote]', - 'tq' => '[quote]', - '/tq' => '[/quote]', - 'quote' => '[quote]', - 'quote=' => '[quote="', - 'quote/='=> '"]', - '/quote' => '[/quote]', - 'ni' => '[color=#0057AF]', - '/ni' => '[/color]', - 'br' => '[color=#BB6622]', - '/br' => '[/color]', - 'po' => '[color=#FF8800]', - '/po' => '[/color]', - 'url' => '[url]', - 'url=' => '[url=', - 'url/=' => ']', - '/url' => '[/url]', - 'i' => '[i]', - '/i' => '[/i]', - 'list' => '[list]', - 'list=' => '[list=', - 'list/=' => ']', - '/list' => '[/list]', - '*' => '[*]', - '/*' => '[/*]', - '?' => '[unknown!]', - '/?' => '[/unknown!]', -}; -use constant tags_html => { - 'ht' => '', - '/ht' => '', - 'fq' => '
', - '/fq' => '
', - 'tq' => '
', - '/tq' => '
', - 'quote' => '
', - 'quote=' => '
', - 'quote/='=> ' wrote:
', - '/quote' => '
', - 'ni' => '', - '/ni' => '', - 'br' => '', - '/br' => '', - 'po' => '', - '/po' => '', - 'url' => '',#think: how to add selfincluding? - 'url=' => '', - '/url' => '', - 'i' => '', - '/i' => '', - 'list' => '
    ', - 'list=' => '
      ', - '/list' => '
', - '/list=' => '', - '*' => '
  • ', - '/*' => '
  • ', - '?' => '[unknown!]', - '/?' => '[/unknown!]', -}; - - -# Function to return an error page -# arguments: 1 - header fields, 2 - page title, 3 - error message, 4 method -sub failpage { - (my $header, my $title, my $message, my $method, my $hyperlink) = @_; - - if (ref($header)) { - foreach my $header_name (keys %$header) { - print http_header_line($header_name, $header->{$header_name}); - } - } - elsif($header ne '') { - print $header; - } - if($method eq 'HEAD') { - print "\n"; - return; - } - my $_title = html_entity_encode_dec($title , 1); - my $_message = html_entity_encode_dec($message , 1); - my $_hyperlink = html_entity_encode_dec($hyperlink, 1); - - print "Content-type: text/html; charset=UTF-8\n\n"; - - print ''."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - if ($title ne '') { - print ' '.$_title.''."\n"; - } - print ' '."\n"; - print ' '."\n"; - if ($title ne '') { - print '

    '.$_title.'

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

    \n"; - if ($message ne '') { - print ' '.$_message.($hyperlink ne '' ? '
    ' : '')."\n"; - } - if ($hyperlink ne '') { - print ' '.$_hyperlink."\n"; - } - print "

    \n"; - } - print ' '."\n"; - print ''."\n"; -} - -sub fail_method { - (my $method, my $allowed) = @_; - - my $status = http_status(HTTP_STATUS->{'method_not_allowed'}); - my $header = - http_header_line('status', $status) . - http_header_allow($allowed); - - return failpage( - $header, - $status, - "The interface does not support the $method method.", - $method - ); -} - -sub fail_content_type -{ - (my $method, my $content_type) = @_; - - my $status = http_status(HTTP_STATUS->{'unsupported_media_type'}); - my $header = http_header_line('status', $status); - - return failpage( - $header, - $status, - "Unsupported Content-type: $content_type.", - $method - ); -} - -sub fail_open_file -{ - (my $method, my $type, my $path) = @_; - - my $status = http_status(HTTP_STATUS->{'not_found'}); - my $header = http_header_line('status', $status); - - return failpage( - $header, - $status, - "Can't open ". - ($type ne '' ? $type : 'file'). - ($path ne '' ? ': "'.$path.'"' : ''). - '.', - $method - ); -} - -sub fail_attachment -{ - (my $method, my $ID) = @_; - - my $status = http_status(HTTP_STATUS->{'not_found'}); - my $header = http_header_line('status', $status); - - return failpage( - $header, - $status, - "Attachment $ID not found.", - $method - ); -} - -sub fail_500 -{ - (my $method, my $text) = @_; - - my $status = http_status(HTTP_STATUS->{'internal_server_error'}); - my $header = http_header_line('status', $status); - - return failpage( - $header, - $status, - $text, - $method - ); -} - -sub redirect -{ - (my $method, my $uri, my $code) = @_; - my $header; - my $status; - if ($code eq '') { - $code = HTTP_STATUS->{'found'}; - } - # https://insanecoding.blogspot.com/2014/02/http-308-incompetence-expected.html - # 301 Moved Permanently - # 302 Found - # 303 See Other - # 307 Temporary Redirect - # 308 Permanent Redirect - $status = http_status($code); - $header = http_header_line('status', $status); - $header .= http_header_location($uri); - - return failpage( - $header, - $status, - '', - $method, - $uri - ); -} - - -# function to obtain address of remote agent -sub get_remote_addr { - if ($ENV{'HTTP_X_FORWARDED_FOR'} =~ /^.+$/) { - return $&; - } - elsif ($ENV{'REMOTE_ADDR'} =~ /^.+$/) { - return $&; - } - else { - return '0.0.0.0'; - } -} - -# functions to get ID/number etc. -sub get_id { - (my $cgi, my $default, my $cgi_name) = @_; - if ($default eq '') { - $default = 0; - } - if ($cgi_name eq '') { - $cgi_name = 'i'; - } - - if ($cgi->{$cgi_name} =~ /^.+$/) { - return int($&); - } - elsif ($ENV{'PATH_INFO'} =~ /^\/(.+)$/) { - return int($1); - } - else { - return int($default); - } -} - -# function to obtain frame number -sub get_frame { - (my $cgi, my $default) = @_; - return get_id($cgi, $default, 'f'); -} - -# function to obtain password -sub get_password { - (my $cgi) = @_; - - if ($cgi->{'p'} =~ /^.+$/) { - return $&; - } - else { - return ''; - } -} - - -sub merge_settings { - my %final_settings; - - foreach my $settings (@_) { - foreach my $ind (keys %$settings) { - $final_settings{$ind} = $settings->{$ind}; - } - } - return %final_settings; -} - - -# BB code stuff -# different & simpler implementation than in post library -# to consider: -# a BBcode library? - -#analyse bbcode text to build tag tree -#TODO make [/*] optional! -sub bbtree { - (my $bb, my $printdebug) = @_; - my %bbtree; - my $ind; - my $tag; - my $tag_name; - my $tag_value; - my $tag_end; - my $level=0; - my $pre_text; - my $debug; - - $ind="_"; - $level=0; - $bbtree{"_.name" } = "ht"; - $bbtree{"_.value" } = ''; - $bbtree{"_.type" } = "tag"; - $bbtree{"_.count" } = 0; - $bbtree{"_.closed"} = 0; - $debug .= debug($printdebug, - "\n". - "\n"); - $bbtree{$final_ind.'.type' } = "tag"; - $bbtree{$final_ind.'.name' } = '/ht'; - $bbtree{ '_.count' }+= 1; - $bbtree{ '_.closed'} = 1; - - return ($debug, %bbtree); -} - -#convert tag tree to final text -sub convtree { - (my $printdebug, my $debug, my $lang, my $bbtree) = @_; - my $out; - my $ind; - my $indd; - my $level = 0; - my $tags = ($lang eq 'html') ? tags_html : tags_bbcode; - my $escape = ($lang eq 'html'); - - # $debug .= debug($printdebug, "\n****\n"); - # foreach my $iiii (keys %tags) { - # $debug .= debug($printdebug, $iiii.'='.$tags->{$iiii}."\n"); - # } - # $debug .= debug($printdebug, "****\n"); - - $level = 0; - $ind = '_'; - $out = ''; - $debug .= debug($printdebug, "\n\n"); - return ($debug, $out); -} - -#bbcode to html, TBD -sub bb_to_html { - (my $bb, my $printdebug) = @_; - my $ht; - my %bbtree; - my $debug; - - ($debug, %bbtree) = bbtree($bb, $printdebug); - ($debug, $ht) = convtree ($printdebug, $debug, 'html', \%bbtree); - - return $ht; -} - -#bbcode to bb, TBD -sub bb_to_bbcode { - (my $bb, my $printdebug) = @_; - my $ht; - my %bbtree; - my $debug; - - ($debug, %bbtree) = bbtree($bb, $printdebug); - ($debug, $ht) = convtree ($printdebug, $debug, 'bb', \%bbtree); - - return $ht; -} - -sub eval_bb { - (my $bb, my $full_url, my $password) = @_; - my $value; - my $before; - my $after; - - my $base_url = $full_url ? - {'scheme' => SCHEME(), 'host' => WEBSITE()} : - {'path' => ''}; - - while ($bb =~ m/###([^#;]*);/g) { - $value = $1; - $before = $`; - $after = $'; - - if ($value =~ /^att&([0-9]+)$/) { - $value = merge_url( - $base_url, - {'path' => CGI_ATTACH_PATH()}, - {'path' => int($1)} - ) - } - elsif ($value =~ /^vw&([0-9]+)$/) { - $value = merge_url( - $base_url, - {'path' => CGI_VIEWER_PATH()}, - {'path' => int($1)} - ) - } - elsif ($value =~ /^fr&([0-9]+)$/) { - $value = merge_url( - $base_url, - {'path' => CGI_FRAME_PATH()}, - {'path' => int($1)} - ) - } - else { - $value = ''; - } - if (($value ne '') && ($password ne '')) { - $value = merge_url( - $value, - {'query' => {'p' => $password}} - ); - } - $bb = $before . $value . $after; - } - return $bb; -} - - -sub html_encode_line { - (my $text, my $non_ascii, my $all) = @_; - my $html; - my $ind; - - $text =~ s/\r\n/\n/gs; - $text =~ s/\r/\n/gs; - - while ($text ne '') { - $ind = index($text, "\n"); - if ($ind >= 0) { - $html .= html_entity_encode_dec(substr($text, 0, $ind), $non_ascii, $all)."
    \n"; - $text = substr($text, $ind+1); - } - else - { - $html .= html_entity_encode_dec($text, 1); - $text = ''; - } - } - return $html; -} - -sub debug { - (my $print, my $text) = @_; - - if ($print) { - print $text; - } - - return $text; -} - - -sub print_html_start { - (my $fh) = @_; - print $fh ''."\n"; - print $fh ''."\n"; -} - -sub print_html_end { - (my $fh) = @_; - print $fh ''."\n"; -} - -sub print_html_head_start { - (my $fh) = @_; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; -} - -sub print_html_head_end { - (my $fh) = @_; - print $fh ' '."\n"; -} - -sub print_html_body_start { - (my $fh) = @_; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh '
    '."\n"; -} - -sub print_html_body_end { - (my $fh, my $hide_credits) = @_; - print $fh '
    '."\n"; - unless ($hide_credits) { - print $fh '

    '."\n"; - print $fh ' '.html_entity_encode_dec(STORY_CREDITS(),1).'
    '."\n"; - print $fh ' '.html_entity_encode_dec(INTF_CREDITS(),1).'
    '."\n"; - print $fh ' source code'."\n"; - print $fh '

    '."\n"; - } - print $fh ' '.html_entity_encode_dec(WEBSITE(),1).''."\n"; - print $fh ' '."\n"; -} - -sub print_html_data { - (my $fh, my $data) = @_; - - foreach my $key (keys %$data) { - unless ($key eq 'content') { - my $val = $data->{$key}; - $val =~ s/(\r)?\n/\n /gs; # does the space make sense in HTML anyway? - print $fh html_encode_line("$key: $val\n", 1); - } - } - print $fh html_encode_line("\n".$data->{'content'}); -} - -sub print_goto { - ( - my $file, - my $state, - my $settings, - my $goto_list, - my $password_ok, - ) = @_; - - my $fh; - my $last_frame; - my $ong_state; - my $password_query; - - $last_frame = int($state->{'last'}); - $ong_state = int($state->{'state'}); - $password_query = url_query_encode({'p', $settings->{'password'}}); - - my $_title = html_entity_encode_dec($settings->{'story'}, 1); - my $_website_name = html_entity_encode_dec(WEBSITE_NAME() , 1); - my $_base_url = html_entity_encode_dec(CGI_PATH() , 1); - - if (ref($file)) { - $fh=$file; - unless (seek($fh, 0, 0)) { - #don't actually fail here - } - } - else { - unless (open_encoded($fh, ">:encoding(UTF-8)", $file)) { - return 0; - } - } - - print_html_start($fh); - print_html_head_start($fh); - - print $fh ' GOTO • '.$_title.' • '.$_website_name.''."\n"; - - print_html_head_end($fh); - print_html_body_start($fh); - - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - print $fh '

    '.$_title.'

    '."\n"; - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - - for (my $frame = 0; ; $frame += 1) { - unless ( - $password_ok || ( - ($frame <= $last_frame) && - ($ong_state >= STATE->{'waiting'}) - ) - ) { - last; - } - my $title; - my $ongtime; - my @time_tab; - my $time_text; - my $timer_color; - my $frame_text; - my $viewer_url; - - $ongtime = $goto_list->{'ongtime-'.$frame}; - $title = $goto_list->{'title-' .$frame}; - if (($ongtime eq '') && ($title eq '')) { - my %frame_data = read_frame_data($frame); - $ongtime = $frame_data{'ongtime'}; - $title = $frame_data{'title'}; - unless (keys %frame_data) { - last; - } - } - - if ($ongtime ne '') { - @time_tab = gmtime($ongtime); - $time_text = sprintf( - '%02d.%02d.%02d %02d:%02d', - $time_tab[3], - $time_tab[4]+1, - $time_tab[5]%100, - $time_tab[2], - $time_tab[1] - ); - } - else { - $time_text = (($frame <= $last_frame) && ($ong_state >= STATE->{'waiting'})) ? - 'EE.EE.EE EE:EE' : '--.--.-- --:--'; - } - if ($title eq '') { - $title = '_'; - } - $timer_color = (($frame > $last_frame) || ($ong_state < STATE->{'waiting'})) ? - 'cz' : ( - (($frame == $last_frame) && ($ong_state < STATE->{'ready'})) ? - 'ni' : 'br' - ); - $frame_text = sprintf('%03d',$frame); - $viewer_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - {'path' => $frame} - ); # TODO: consider static here? - if ($password_ok) { - $viewer_url = merge_url($viewer_url, {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - } - - my $_viewer_url = html_entity_encode_dec($viewer_url, 1); - my $_title = html_entity_encode_dec($title , 1); - - print $fh ' '.$frame_text.' '.$time_text.' '.$_title.'
    '."\n"; - } - print $fh '
    '."\n"; - - print $fh ' '."\n"; - - print $fh '
    '."\n"; - - print_html_body_end($fh, $ong_state == STATE->{'inactive'}); - print_html_end($fh); - - unless (ref($file)) { - close ($fh); - } - else { - truncate ($fh , tell($fh)); - } - - return 1; -} - -sub print_viewer_page { - ( - my $file, - my $context, - my $state, - my $settings, - my $frame_data, - my $prev_frame_data, - my $next_frame_data, - my $words_data, - ) = @_; - my $fh; - - my $launch = $context->{'launch'}; - my $access = $context->{'access'}; - my $password_ok = $context->{'password_ok'}; - my $static = $context->{'static'}; - - my $goto = int($context->{'goto'}); - my $frame = int($context->{'frame'}); - my $text_mode = int($context->{'text_mode'}); - my $timer_unlocked = int($context->{'timer_unlocked'}); - my $timer = int($context->{'timer'}); - # my $words_page = int($context->{'words_page'}); - - my $prev_frame = $frame - 1; - my $next_frame = $frame + 1; - - my $story = $settings->{'story'}; - my $title = $frame_data->{'title'}; - my $command = ($frame_data->{'command'} ne '') ? - $frame_data->{'command'} : - $next_frame_data->{'title'}; - - my $last_frame = int($state->{'last'}); - my $ong_state = int($state->{'state'}); - - my $width = int($frame_data->{'width'}); - my $height = int($frame_data->{'height'}); - my $frame_type = $frame_data->{'frametype'}; - - my $timer_color_h = (($timer_unlocked >= 1) || ($ong_state >= STATE->{'ready'})) ? 'br' : 'ni'; - my $timer_color_m = (($timer_unlocked >= 2) || ($ong_state >= STATE->{'ready'})) ? 'br' : 'ni'; - my $timer_color_s = (($timer_unlocked >= 3) || ($ong_state >= STATE->{'ready'})) ? 'br' : 'ni'; - - my $timer_h; - my $timer_m; - my $timer_s; - if ( - ($timer > 0) || - (($timer >= 0) && ($frame == 0)) - ) { - $timer_s = sprintf('%02d', $timer % 60); - $timer_h = int($timer / 60); - $timer_m = sprintf('%02d', $timer_h % 60); - $timer_h = sprintf('%02d', $timer_h / 60); - } - elsif (($timer >= -15) && ($ong_state >= STATE->{'ready'})) { - $timer_h = '00'; - $timer_m = '00'; - $timer_s = 'NG'; - } - else { - $timer_h = 'EE'; - $timer_m = 'EE'; - $timer_s = 'EE'; - } - - my $words_posts = int($words_data->{'posts'}); - my $words_link_text = 'Words'.(($words_posts > 0) ? "[$words_posts]" : ''); - - my $prev_available = (($frame > 0) && $access); - my $next_available = ($launch || $password_ok || ($next_frame <= $last_frame)); - my $prefetch_prev = ( - $password_ok || - ($prev_frame < $last_frame) || ( # avoid unseen trigger! - ($prev_frame <= $last_frame) && - ($ong_state >= STATE->{'ready'}) - ) - ); - my $prefetch_next = ( - $password_ok || - ($next_frame < $last_frame) || ( # avoid unseen trigger! - ($next_frame <= $last_frame) && - ($ong_state >= STATE->{'ready'}) - ) - ); - my $show_timer = ( - ( - $access && $launch - ) || ( - ($frame == $last_frame) && ( - ($ong_state == STATE->{'waiting'}) || - ($ong_state == STATE->{'ready'}) - ) - ) - ); - my $show_command = ( - $launch || - $password_ok || - (!$access) || - ($frame < $last_frame) || ( - ($ong_state >= STATE->{'ready'}) && - $context->{'show_command'} - ) - ); - my $show_command_link = ($next_available || (!$access)); - my $show_command_cursor = ((!$next_available) || ($command eq '')); - my $show_words = ($password_ok || ($access && !$launch)); - - my $frame_indirect = !( - (!$access) || ( - ($frame <= $last_frame) && - ($ong_state > STATE->{'inactive'}) - ) - ); - my $prevframe_indirect = !($prev_frame <= $last_frame); - my $nextframe_indirect = !($next_frame <= $last_frame); - - my $password_query; - - my $base_url = CGI_PATH(); - my $timer_url = CGI_TIMER_PATH(); - my $viewer_full_url = merge_url( - {'scheme' => SCHEME(), 'host' => WEBSITE()}, - {'path' => CGI_VIEWER_PATH()}, - {'path' => $frame} - ); - my $viewer_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - {'path' => $frame} - ); - my $viewer_0_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - {'path' => 0} - ); - my $viewer_prev_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - {'path' => $prev_frame} - ); - my $viewer_next_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - {'path' => $next_frame} - ); - my $viewer_last_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - {'path' => ($static ? -1 : $last_frame)} - ); - my $goto_url = ($goto) ? - CGI_GOTO_PATH() : - merge_url( - {'path' => $viewer_url}, - { - 'query' => {'g' => 1}, - 'fragment' => 'goto' - } - ); - - unless ($password_ok) { - my $page_file; - $viewer_0_url = $base_url; - if ($prev_frame == 0) { - $viewer_prev_url = $viewer_0_url; - } - else { - $page_file = get_page_file($prev_frame, $prev_frame_data, $settings); - if (_x_encoded('-f', - join_path(PATH_SEPARATOR(), WWW_PATH() , $page_file) - )) { - $viewer_prev_url = merge_url( - {'path' => $base_url}, - {'path' => $page_file} - ); - } - } - if ($next_frame < $last_frame) { - $page_file = get_page_file($next_frame, $next_frame_data, $settings); - if (_x_encoded('-f', - join_path(PATH_SEPARATOR(), WWW_PATH() , $page_file) - )) { - $viewer_next_url = merge_url( - {'path' => $base_url}, - {'path' => $page_file} - ); - } - } - if ( - $goto && - (_x_encoded('-f',WWW_GOTO_PATH())) - ) { - $goto_url = CGI_LIST_PATH(); - } - } - my $bbcode_url = ($text_mode == TEXT_MODE->{'bb'}) ? - merge_url( - {'path' => CGI_BBCODE_PATH()}, - {'path' => $frame} - ) : - merge_url ( - $viewer_url, - { - 'query'=>{ - 'b' => TEXT_MODE->{'bb'} - }, - 'fragment'=>'insb' - } - ); - my $info_url = ($text_mode == TEXT_MODE->{'info'}) ? - merge_url( - {'path' => CGI_INFO_PATH()}, - {'path' => $frame} - ) : - merge_url ( - $viewer_url, - { - 'query'=>{ - 'b' => TEXT_MODE->{'info'} - }, - 'fragment'=>'insb' - } - ); - my $words_url = merge_url ( - $viewer_url, - { - 'query'=>{ - 'b' => TEXT_MODE->{'words'} - }, - 'fragment'=>'insw' - } - ); - my $frame_file; - my $frame_url; - my $frame_prev_url; - my $frame_next_url; - my $frame_normal_url; - my $frame_full_url; - $frame_file = get_frame_file($frame, $frame_data, $settings); - $frame_normal_url = merge_url( - {'path' => CGI_PATH()}, - {'path' => $frame_file} - ); - $frame_url = $frame_indirect ? - merge_url( - {'path' => CGI_FRAME_PATH()}, - {'path' => $frame} - ) : - $frame_normal_url; - $frame_full_url = merge_url( - {'scheme' => SCHEME(), 'host' => WEBSITE()}, - {'path' => $frame_normal_url} - ); - if ($prevframe_indirect) { - $frame_prev_url = merge_url( - {'path' => CGI_FRAME_PATH()}, - {'path' => $prev_frame} - ); - } - else { - $frame_prev_url = merge_url( - {'path' => CGI_PATH()}, - {'path' => get_frame_file($prev_frame, $prev_frame_data, $settings)} - ); - } - if ($nextframe_indirect) { - $frame_next_url = merge_url( - {'path' => CGI_FRAME_PATH()}, - {'path' => $next_frame} - ); - } - else { - $frame_next_url = merge_url( - {'path' => CGI_PATH()}, - {'path' => get_frame_file($next_frame, $next_frame_data, $settings)} - ); - } - - if ($password_ok) { - $password_query = url_query_encode({'p', $settings->{'password'}}); - $goto_url = merge_url($goto_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $info_url = merge_url($info_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $words_url = merge_url($words_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $bbcode_url = merge_url($bbcode_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $viewer_url = merge_url($viewer_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $viewer_0_url = merge_url($viewer_0_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $viewer_prev_url = merge_url($viewer_prev_url, {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $viewer_next_url = merge_url($viewer_next_url, {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $viewer_last_url = merge_url($viewer_last_url, {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - if ($frame_indirect) { - $frame_url = merge_url($frame_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - } - if ($prevframe_indirect) { - $frame_prev_url= merge_url($frame_prev_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - } - if ($nextframe_indirect) { - $frame_next_url= merge_url($frame_next_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - } - } - my $_password = $password_ok ? html_entity_encode_dec($settings->{'password'}, 1) : ''; - my $_action_url = html_entity_encode_dec(CGI_VIEWER_PATH(), 1); - my $_base_url = html_entity_encode_dec($base_url , 1); - my $_goto_url = html_entity_encode_dec($goto_url , 1); - my $_info_url = html_entity_encode_dec($info_url , 1); - my $_words_url = html_entity_encode_dec($words_url , 1); - my $_bbcode_url = html_entity_encode_dec($bbcode_url , 1); - my $_timer_url = html_entity_encode_dec($timer_url , 1); - my $_viewer_full_url = html_entity_encode_dec($viewer_full_url , 1); - my $_viewer_url = html_entity_encode_dec($viewer_url , 1); - my $_viewer_0_url = html_entity_encode_dec($viewer_0_url , 1); - my $_viewer_prev_url = html_entity_encode_dec($viewer_prev_url , 1); - my $_viewer_next_url = html_entity_encode_dec($viewer_next_url , 1); - my $_viewer_last_url = html_entity_encode_dec($viewer_last_url , 1); - my $_frame_url = html_entity_encode_dec($frame_url , 1); - my $_frame_prev_url = html_entity_encode_dec($frame_prev_url , 1); - my $_frame_next_url = html_entity_encode_dec($frame_next_url , 1); - my $_frame_full_url = html_entity_encode_dec($frame_full_url , 1); - - my $_story = html_entity_encode_dec($story , 1); - my $_title = html_entity_encode_dec($title , 1); - my $_command = html_entity_encode_dec($command , 1); - my $_frame_type = html_entity_encode_dec($frame_type, 1); - - my $_website_name = html_entity_encode_dec(WEBSITE_NAME(), 1); - - if ($text_mode == TEXT_MODE->{'info'}) { - if ($show_command) { - $frame_data->{'command'} = $command; - } - if ($access) { - $frame_data->{'frame'} = $frame_file; - } - if ($frame_data->{'page'} eq '') { - unless (($access) && ($frame < $last_frame)) { - $frame_data->{'page'} = ''; - } - else { - $frame_data->{'page'} = get_page_file($frame, $frame_data, $settings); - } - } - } - - # everything determined, now start generating - - if (ref($file)) { - $fh=$file; - unless (seek($fh, 0, 0)) { - #don't actually fail here - } - } - else { - unless (open_encoded($fh, ">:encoding(UTF-8)", $file)) { - return 0; - } - } - - print_html_start($fh); - print_html_head_start($fh); - - print $fh ' '.$_title; - if ($story ne $title) { - print $fh ' • '.$_story; - } - print $fh ' • '.$_website_name.''."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - if ($prev_available) { - print $fh ' '."\n"; - if ($prefetch_prev) { - print $fh ' '."\n"; - print $fh ' '."\n"; - } - } - if ($next_available) { - print $fh ' '."\n"; - if ($prefetch_next) { - print $fh ' '."\n"; - print $fh ' '."\n"; - } - } - if ($show_timer) { - print $fh ' '."\n"; - } - - print_html_head_end($fh); - print_html_body_start($fh); - - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - print $fh '

    '.$_title.'

    '."\n"; - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - print $fh '
    '."\n"; - - print $fh ' '.$frame.''."\n"; - - print $fh '
    '."\n"; - print $fh '
    '."\n"; - - if ($text_mode == TEXT_MODE->{'info'}) { - print $fh '
    '."\n"; - - print_html_data($fh, $frame_data); - - print $fh '
    '."\n"; - } - elsif ($text_mode == TEXT_MODE->{'bb'}) { - print $fh '
    '."\n"; - - print $fh '[quote][center][size=200]'.$_title.'[/size]
    '."\n"; - print $fh '[url='.$_viewer_full_url.'][img]'.$_frame_full_url.'[/img][/url][/center]
    '."\n"; - print $fh html_encode_line( - bb_to_bbcode( - eval_bb( - $frame_data->{'content'}, - 1 - ) - ) - ); - print $fh '[/quote]'."\n"; - - print $fh '
    '."\n"; - } - elsif ($frame_data->{'content'} ne '') { - print $fh '
    '."\n"; - print $fh bb_to_html( - eval_bb( - $frame_data->{'content'}, - 0, - $password_ok ? $settings->{'password'} : '' - ) - )."\n"; - print $fh '
    '."\n"; - } - - print $fh '
    '."\n"; - - if ($show_timer) { - print $fh ' '; - print $fh '['.$timer_h.''; - print $fh ':'.$timer_m.''; - print $fh ':'.$timer_s.']'; - print $fh '
    '."\n"; - } - print $fh ' >'; - if ($show_command_link) { - print $fh ''; - } - if ($show_command) { - print $fh $_command; - } - if ($show_command_cursor) { - print $fh '_'; - } - if ($show_command_link) { - print $fh ''; - } - print $fh "
    \n"; - print $fh "
    \n"; - - print $fh ' \n"; - - if ($goto) { - print $fh ' \n"; - } - - print $fh "
    \n"; - - if (($text_mode == TEXT_MODE->{'words'}) && $show_words) { - print_comments($fh, $context, $settings, $words_data); - } - - print_html_body_end($fh, $ong_state == STATE->{'inactive'}); - print_html_end($fh); - - - unless (ref($file)) { - close ($fh); - } - else { - truncate ($fh , tell($fh)); - } - - return 1; -} - -sub print_comments { - (my $fh, my $context, my $settings, my $words_data) = @_; - - my $password_ok = $context->{'password_ok'}; - my $frame = int($context->{'frame'}); - my $page = int($context->{'words_page'}); - my $post_count = int($words_data->{'posts'}); - my $id_start = $page * COMMENT_PAGE_LENGTH(); - my $id_stop = $id_start + COMMENT_PAGE_LENGTH(); - my $older = ($page > 0) ? ($page-1) : ''; - my $newer; - my $password_query; - if ($id_stop >= $post_count) { - $id_stop = $post_count; - } - else { - $newer = $page+1; - } - my $links; - - my $words_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - { - 'path' => $frame, - 'query' => {'b' => TEXT_MODE->{'words'}}, - } - ); - my $older_url = merge_url( - $words_url, - { - 'query' => {'i' => $page-1}, - 'fragment' => 'insw', - 'append_query' => 1 - } - ); - my $newer_url = merge_url( - $words_url, - { - 'query' => {'i' => $page+1}, - 'fragment' => 'insw', - 'append_query' => 1 - } - ); - - if ($password_ok) { - $password_query = url_query_encode({'p', $settings->{'password'}}); - $older_url = merge_url($older_url, {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $newer_url = merge_url($older_url, {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - } - - my $_password = $password_ok ? html_entity_encode_dec($settings->{'password'}, 1) : ''; - my $_post_url = html_entity_encode_dec(CGI_WORDS_PATH(), 1); - my $_older_url = html_entity_encode_dec($older_url, 1); - my $_newer_url = html_entity_encode_dec($newer_url, 1); - - if (($older ne '') || ($newer ne '')) { - $links .= ' '."\n"; - } - - print $fh '
    '."\n"; - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - print $fh '

    Words

    '."\n"; - print $fh '
    '."\n"; - - if ($links ne '') { - print $fh $links; - } - - print $fh '
    '."\n"; - - if ($post_count > 0) { - for (my $i=$id_start; $i<$id_stop; ++$i) { - my $ID = $words_data->{'content'}->[$i]; - my %post_data = read_words($ID); - - my $post_time = int($post_data{'posttime'}); - my $edit_time = int($post_data{'edittime'}); - - my $post_time_text; - my $edit_time_text; - - if ($post_time != 0) { - my @time_tab = gmtime($post_time); - $post_time_text = sprintf( - '%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[0] - ); - } - if (($edit_time !=0) && ($edit_time != $post_time)) { - my @time_tab = gmtime($edit_time); - $edit_time_text = sprintf( - '%04d.%02d.%02d %02d:%02d UTC', - $time_tab[5]+1900, - $time_tab[4]+1, - $time_tab[3], - $time_tab[2], - $time_tab[1] - ); - } - my $quote_url = merge_url( - {'path' => CGI_WORDS_PATH()}, - { - 'query' => { - 'f' => $frame, - 'quote' => $ID, - 'p' => ($password_ok ? $settings->{'password'} : '') - } - } - ); - my $edit_url = merge_url( - {'path' => CGI_WORDS_PATH()}, - { - 'query' => { - 'f' => $frame, - 'edit' => $ID, - 'key' => $post_data{'key'}, - 'username' => $post_data{'name'}, - 'p' => ($password_ok ? $settings->{'password'} : '') - } - } - ); - my $remove_url = merge_url( - {'path' => CGI_WORDS_PATH()}, - { - 'query' => { - 'f' => $frame, - 'remove' => $ID, - 'key' => $post_data{'key'}, - 'username' => $post_data{'name'}, - 'p' => ($password_ok ? $settings->{'password'} : '') - } - } - ); - - my $_ID = html_entity_encode_dec($ID, 1); - my $_name = html_entity_encode_dec($post_data{'name'}, 1); - my $_quote_url = html_entity_encode_dec($quote_url, 1); - my $_edit_url = html_entity_encode_dec($edit_url, 1); - my $_remove_url = html_entity_encode_dec($remove_url, 1); - - print $fh '
    '."\n"; - print $fh ' '."\n"; - print $fh '
    '."\n"; - print $fh bb_to_html( - eval_bb( - $post_data{'content'}, - 0, - $password_ok ? $settings->{'password'} : '' - ) - )."\n"; - print $fh '
    '."\n"; - print $fh '
    '."\n"; - print $fh '
    '."\n"; - } - } - - print $fh '
    '."\n"; - print $fh ' Your words:'."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh '
    Your name:
    Optional password: (if you want to edit later)
    Leave this empty: '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh '
    '."\n"; - print $fh ' '."\n"; - if ($password_ok) { - print $fh ' '."\n"; - } - print $fh '
    '."\n"; - print $fh '
    '."\n"; - - if ($links ne '') { - print $fh $links; - } - - print $fh '
    '."\n"; -} - -sub write_index { - ( - my $state, - my $settings, - my $pass, - my $mode, - my $pause - ) = @_; - my $fh; - my $r = 1; - my $ong_state = int($state->{'state'}); - - unless (open_encoded($fh, ">:encoding(UTF-8)", WWW_INDEX_PATH())) { - return 0; - } - - # normal running story - if ($ong_state > STATE->{'inactive'}) { - my %default = read_default(); - my %frame_data = read_frame_data(0, \%default); - my %next_frame_data= read_frame_data(1, \%default); - my %words_data = read_words_list( - 0, # frame ID - 1, # header only - ); - - $r = print_viewer_page( - $fh, - { - 'launch' => 0, - 'frame' => 0, - 'access' => 1, - 'password_ok' => 0, - 'timer_unlocked' => 3, # not relevant - 'timer' => 0, # not relevant - 'static' => 1, - 'show_command' => 1, - 'text_mode' => TEXT_MODE->{'normal'}, - 'words_page' => 0, # not relevant - 'goto' => 0 - }, - $state, - $settings, - \%frame_data, - \%default, # prev - \%next_frame_data, - \%words_data - ); - } - # no conditions met, pretend a normal Apache2 index - elsif ($pass != 1) { - my $index_of = CGI_PATH; - $index_of =~ s/\/$//g; - - my $_index_of = html_entity_encode_dec($index_of , 1); - my $_2words_date = html_entity_encode_dec(INTF_DATE(), 1); - my $_coin_date = html_entity_encode_dec(COIN_DATE(), 1); - my $_website = html_entity_encode_dec(WEBSITE() , 1); - - print_html_start ($fh); - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' Index of '.$_index_of.''."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh '

    Index of '.$_index_of.'

    '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh ' '."\n"; - print $fh '
    [ICO]NameLast modifiedSizeDescription

    [DIR]Parent Directory  -  
    [DIR]2words/'.$_2words_date.' -  
    [DIR]coin/'.$_coin_date.' - Coincidence

    '."\n"; - print $fh '
    Apache/2.2.22 (Debian) Server at '.$_website.' Port 80
    '."\n"; - print $fh ' '."\n"; - print_html_end ($fh); - } - # the launch index - else { - my %default = read_default(); - my %frame_data = read_frame_data(0, \%default); - my %next_frame_data= read_frame_data(1, \%default); - my %coin_data = read_coincidence(); - - if (($mode == INTF_STATE->{'>'}) && $pause) { - $r = print_viewer_page( - $fh, - { - 'launch' => 1, - 'frame' => 0, - 'access' => 1, - 'password_ok' => 0, - 'timer_unlocked' => 3, - 'timer' => 0, - 'static' => 1, - 'show_command' => 1, - 'text_mode' => TEXT_MODE->{'normal'}, - 'words_page' => 0, # not relevant - 'goto' => 0 - }, - $state, - $settings, - \%frame_data, - \%default, # prev - \%next_frame_data, - {'posts' => 0} # words_data - ); - return $r; - } - - my $index_of = CGI_PATH; - $index_of =~ s/\/$//g; - my $title; - my $frame_file; - my $undertext = ''; - my $show_parent_dir = 0; - my $show_yb = 0; - my $show_folders = 0; - my $timer = ''; - my $timer_color = 'ni'; - if ($mode == INTF_STATE->{'>'}) { - $title = $settings->{'story'}; # $frame_data{'title'} ? - $frame_file = 'intf-tr.gif'; - $undertext = '...'; - $timer = '--'; - } - elsif ($mode == INTF_STATE->{'<<'}) { - $title = 'Index of'; - $frame_file = 'intf-ll.gif'; - $show_parent_dir = 1; - $show_yb = 1; - $timer = 'EE'; - $timer_color = 'br'; - } - elsif ($mode == INTF_STATE->{'>>'}) { - $title = 'Index of'; - $frame_file = 'intf-pp.gif'; - $show_parent_dir = 1; - $show_yb = 1; - $timer = 'EE'; - } - else - { - $title = 'Index of '.$index_of; - $frame_file = 'intf-kw.gif'; - $show_parent_dir = 1; - $show_folders = 1; - } - my $frame_url = merge_url( - {'path' => CGI_PATH()}, - {'path' => $frame_file} - ); - my $coin_server = $coin_data{'server'}; - - my $_title = html_entity_encode_dec($title , 1); - my $_website_name = html_entity_encode_dec(WEBSITE_NAME() , 1); - my $_frame_url = html_entity_encode_dec($frame_url , 1); - my $_undertext = html_entity_encode_dec($undertext , 1); - my $_2words_date = html_entity_encode_dec(INTF_DATE() , 1); - my $_coin_date = html_entity_encode_dec(COIN_DATE() , 1); - my $_coin_server = html_entity_encode_dec($coin_server , 1); - my $_2words_url = html_entity_encode_dec(CGI_2WORDS_PATH(), 1); - my $_coin_url = html_entity_encode_dec(CGI_COIN_PATH() , 1); - - print_html_start($fh); - print_html_head_start($fh); - - print $fh ' '.$_title.' • '.$_website_name.''."\n"; - - print_html_head_end($fh); - print_html_body_start($fh); - - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - print $fh '

    '.$_title.'

    '."\n"; - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - print $fh '
    '."\n"; - - print $fh ' 0'."\n"; # title="'.$_title.'" - - print $fh '
    '."\n"; - print $fh '
    '."\n"; - - print $fh '
    '."\n"; - - if ($show_parent_dir) { - print $fh ' [DIR] Parent Directory
    '."\n"; - } - if ($show_folders) { - print $fh ' [DIR] 2words/ '.$_2words_date.' -
    '."\n"; - print $fh ' [DIR] coin/ '.$_coin_date.' - '.$_coin_server."\n"; - } - elsif ($show_yb) { - print $fh ' [DIR] yyyyb/'."\n"; - } - if ($undertext ne '') { - print $fh ' '.$_undertext."\n"; - } - - print $fh '
    '."\n"; - - if ($timer ne '') { - print $fh '
    '."\n"; - - print $fh ' ['.$timer.''; - print $fh ':'.$timer.''; - print $fh ':'.$timer.']
    '."\n"; - - if ($undertext ne '') { - print $fh '>'.$_undertext.'_'."\n"; - } - print $fh "
    \n"; - } - - print $fh "
    \n"; - - print_html_body_end($fh, $ong_state == STATE->{'inactive'}); - print_html_end($fh); - } - close ($fh); - return $r -} - -sub write_static_viewer_page { - ( - my $frame, - my $state_ref, - my $settings_ref, - my $default_ref, - my $frame_data_ref, - my $prev_frame_data_ref, - my $next_frame_data_ref, - my $words_data_ref - ) = @_; - - my %state; - my %settings; - my %default; - my %frame_data; - my %prev_frame_data; - my %next_frame_data; - my %words_data; - - my $file; - - $frame = int($frame); - my $prev_frame = $frame -1; - my $next_frame = $frame +1; - - %state = (ref ($state_ref)) ? - %$state_ref : - read_state(); - my $ong_state = int($state{'state'}); - my $last_frame = int($state{'last'}); - - unless ($ong_state > STATE->{'inactive'}) { - return 0; - } - unless ( - ($frame >= 0) && ( - ($frame < $last_frame) || ( - ($frame <= $last_frame) && - ($ong_state >= STATE->{'end'}) - ) - ) - ) { - return 0; - } - - %settings = (ref ($settings_ref)) ? - %$settings_ref : - read_settings(); - %default = (ref ($default_ref)) ? - %$default_ref : - read_default(); - - %frame_data = (ref ($frame_data_ref)) ? - %$frame_data_ref : - read_frame_data($frame); - - %prev_frame_data = (ref ($prev_frame_data_ref)) ? - %$prev_frame_data_ref : ( - ($prev_frame >= 0) ? - read_frame_data($prev_frame) : - %default - ); - - %next_frame_data = (ref ($next_frame_data_ref)) ? - %$next_frame_data_ref : - read_frame_data($next_frame); - - %words_data = (ref ($words_data_ref)) ? - %$words_data_ref : - read_words_list( - $frame, # frame ID - 1, # header only - ); - - %frame_data = merge_settings(\%default, \%frame_data); - %prev_frame_data = merge_settings(\%default, \%prev_frame_data); - %next_frame_data = merge_settings(\%default, \%next_frame_data); - - $file = get_page_file($frame, \%frame_data, \%settings); - $file = join_path(PATH_SEPARATOR(), WWW_PATH(), $file); - - return print_viewer_page( - $file, - { - 'launch' => 0, - 'frame' => $frame, - 'access' => 1, - 'password_ok' => 0, - 'timer_unlocked'=> 3, # not relevant - 'timer' => 0, # not relevant - 'static' => 1, - 'show_command' => 1, - 'text_mode' => TEXT_MODE->{'normal'}, - 'words_page' => 0, # not relevant - 'goto' => 0 - }, - \%state, - \%settings, - \%frame_data, - \%prev_frame_data, - \%next_frame_data, - \%words_data - ); -} - -sub write_static_goto { - (my $state_ref, my $settings_ref, my $goto_ref) = @_; - my %state; - my %settings; - my %goto_list; - - %state = (ref ($state_ref)) ? - %$state_ref : - read_state(); - %settings = (ref ($settings_ref)) ? - %$settings_ref : - read_settings(); - %goto_list = (ref ($goto_ref)) ? - %$goto_ref : - read_goto(); - - return print_goto( - WWW_GOTO_PATH(), - \%state, - \%settings, - \%goto_list, - 0, # password OK - ); -} - -# ONG the frame + attachment & stuff. NOT update state file. -sub ong { - ( - my $ID, my $ongtime, my $timer, my $update, my $print, - my $settings_ref, my $default_ref, my $data_ref, my $goto_ref - ) = @_; - my @files; - my $cfrt; - my $intf; - my $frame; - my $frame_data_path; - my $write_data; - my $in_path; - my $out_path; - my $r; - my %settings; - my %default; - my %frame_data; - my %frame_full_data; - my %goto_list; - - if ($ongtime eq '') { - $ongtime = time(); - } - - if ($ID eq 'i') { - $intf = 1; - } - elsif ($ID eq 'c') { - $cfrt = 1; - } - else { - $frame = int($ID); - } - - if ($intf) { - @files = ( - 'intf-00.gif', - 'intf-00_04.gif', - 'intf-00_08.gif', - 'intf-00_10.gif', - 'intf-01.gif', - 'intf-01_.gif', - 'intf-02.gif', - 'intf-02_.gif', - 'intf-04.gif', - 'intf-04_.gif', - 'intf-08.gif', - 'intf-08_.gif', - 'intf-10.gif', - 'intf-10_.gif', - 'intf-20.gif', - 'intf-20_.gif', - 'intf-kw.gif', - 'intf-ll.gif', - 'intf-pp.gif', - 'intf-tr.gif', - ); - } - else { - %settings = (ref ($settings_ref)) ? - %$settings_ref : - read_settings(); - %default = (ref ($default_ref)) ? %$default_ref : read_default(); - $frame_data_path = $cfrt ? - DATA_NOACCESS_PATH() : - join_path(PATH_SEPARATOR(), DATA_PATH(), $frame); - %frame_data = (ref ($data_ref)) ? - %$data_ref : - read_frame_data($frame_data_path); - %frame_full_data = merge_settings(\%default, \%frame_data); - @files = (get_frame_file($frame, \%frame_full_data, \%settings), ); - unless ($cfrt) { - %goto_list = (ref ($goto_ref)) ? - %$goto_ref : - read_goto(); - for (my $i=0; ;$i+=1) { - my %file_data = read_attachment($i); - if ($file_data{'frame'} eq '') { - last; - } - if (int($file_data{'frame'}) != $frame) { - next; - } - if ($file_data{'content'} ne '') { - next; - } - unshift @files, $file_data{'filename'}; - } - if ( - (!$update) || - ($frame_full_data{'ongtime'} eq '') - ) { - $frame_data {'ongtime'} = $ongtime; - $frame_full_data{'ongtime'} = $ongtime; - $write_data = 1; - } - if ( - ($timer ne '') && ( - (!$update) || - ($frame_full_data{'timer'} eq '') - ) - ) { - $frame_data{'timer'} = int($timer); - $write_data = 1; - } - if ($write_data) { - $r = write_frame_data($frame_data_path, \%frame_data); - unless ($r) { - print STDERR "fail writing $frame_data_path\n"; - if ($print) { - print "write frame data fail\n"; - } - return $r; - } - } - $goto_list{'title-' .$frame} = $frame_full_data{'title'}; - $goto_list{'ongtime-'.$frame} = $frame_full_data{'ongtime'}; - $r = write_goto('', \%goto_list); - unless ($r) { - print STDERR "fail writing ".DATA_LIST_PATH()."\n"; - if ($print) { - print "write GOTO list fail\n"; - } - return $r; - } - } - } - foreach my $file (@files) { - $in_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $file); - $out_path = join_path(PATH_SEPARATOR(), WWW_PATH() , $file); - if ($print) { - print $in_path.' -> '.$out_path; - } - $r = copy_encoded($in_path, $out_path); - if ($print) { - print (($r) ? " OK\n" : " FAIL\n"); - } - unless ($r) { - print STDERR "fail copy $in_path $out_path\n"; - return $r - } - } - - return 1; -} - - -sub get_frame_file { - (my $frame, my $frame_data, my $settings) = @_; - my $file; - my $pattern; - - if ($frame_data->{'frame'} ne '') { - $file = $frame_data->{'frame'}; - } - else { - $pattern = validate_filename($settings->{'frame'}, '%d.%ext'); - $file = sprintf( - $pattern, - int($frame), $frame_data->{'ext'} - ); - } - return validate_filename($file); -} - -sub get_page_file { - (my $frame, my $frame_data, my $settings) = @_; - my $file; - my $pattern; - - if ($frame == 0) { - return 'index.htm'; - } - if ($frame_data->{'page'} ne '') { - $file = $frame_data->{'page'}; - } - else { - $pattern = validate_filename($settings->{'frame'}, '%d.%ext'); - $file = sprintf( - $pattern, - int($frame), 'htm' - ); - } - return validate_filename($file); -} - -sub validate_filename { - (my $filename, my $fallback) = @_; - if ($fallback eq '') { - $fallback = ''; - } - - # TODO: more checks - - if ($filename =~ /^\./) { - return $fallback; - } - if (index($filename, PATH_SEPARATOR()) >= 0) { - return $fallback; - } - return $filename; -} - -sub validate_frame_data { - (my $data_in) = @_; - my %data = %$data_in; - - if ($data{'ongtime'} ne '') { - $data{'ongtime'} = int($data{'ongtime'}); - } - if ($data{'timer'} ne '') { - $data{'timer'} = int($data{'timer'}); - } - if ($data{'width'} ne '') { - $data{'width'} = int($data{'width'}); - } - if ($data{'height'} ne '') { - $data{'height'} = int($data{'height'}); - } - if ($data{'page'} ne '') { - $data{'page'} = validate_filename($data{'page'}); - } - if ($data{'frame'} ne '') { - $data{'frame'} = validate_filename($data{'frame'}); - } - - return %data; -} - -sub validate_settings { - (my $data_in) = @_; - my %data = %$data_in; - - if ($data{'ongtime'} ne '') { - $data{'ongtime'} = int($data{'ongtime'}); - } - if ($data{'dynamicongtime'} ne '') { - $data{'dynamicongtime'} = int($data{'dynamicongtime'}); - } - if ($data{'firstongtime'} ne '') { - $data{'firstongtime'} = int($data{'firstongtime'}); - } - if ($data{'last'} ne '') { - $data{'last'} = int($data{'last'}); - } - $data{'frame'} = validate_filename($data{'frame'}, '%d.%s'); - - return %data; -} - -sub validate_state { - (my $data_in) = @_; - my %data = %$data_in; - - if ($data{'state'} ne '') { - $data{'state'} = int($data{'state'}); - } - if ($data{'last'} ne '') { - $data{'last'} = int($data{'last'}); - } - if ($data{'nextong'} ne '') { - $data{'nextong'} = int($data{'nextong'}); - } - - return %data; -} - -sub validate_words_list { - (my $data_in, my $not_list) = @_; - my %data = %$data_in; - - if ($data{'ongtime'} ne '') { - $data{'ongtime'} = int($data{'ongtime'}); - } - - if ($not_list) { - my $id_list = ''; - foreach my $ID (split(/\r?\n/, $data{'content'})) { - $ID = validate_filename($ID); - if ($ID ne '') { - $id_list .= $ID."\n"; - } - } - $data{'content'} = $id_list; - } - else { - my @id_list; - foreach my $ID (@{$data{'content'}}) { - - $ID = validate_filename($ID); - if ($ID ne '') { - push @id_list, $ID; - } - } - $data{'content'} = [@id_list]; - } - - return %data; -} - -sub validate_words { - (my $data_in) = @_; - my %data = %$data_in; - - if ($data{'posttime'} ne '') { - $data{'posttime'} = int($data{'posttime'}); - } - if ($data{'edittime'} ne '') { - $data{'edittime'} = int($data{'edittime'}); - } - - return %data; -} - -sub validate_story { - (my $data_in) = @_; - my %data = %$data_in; - - if ($data{'id'} ne '') { - $data{'id'} = int($data{'id'}); - } - if ($data{'pass'} ne '') { - $data{'pass'} = int($data{'pass'}); - } - if ($data{'state'} ne '') { - $data{'state'} = int($data{'state'}); - } - - return %data; -} - -sub validate_goto { - (my $data_in) = @_; - my %data = %$data_in; - - foreach my $key (keys %data) { - if ($key =~ /^ongtime-([0-9]+)$/) { - my $new_key = 'ongtime-'.int($1); - $data{$new_key} = int($data{$key}); - if ($new_key != $key) { - delete $data{$key}; - } - } - } - - return %data; -} - -sub validate_attachment { - (my $data_in) = @_; - my %data = %$data_in; - - if ($data{'frame'} ne '') { - $data{'frame'} = int($data{'frame'}); - } - $data{'filename'} = validate_filename($data{'filename'}); - - return %data; -} - -sub validate_coincidence { - (my $data_in) = @_; - my %data = %$data_in; - - if ($data{'server'} ne '') { - $data{'server'} = int($data{'server'}); - } - - return %data; -} - -sub read_frame_data { - (my $f, my $default) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # frame ID - $file = join_path(PATH_SEPARATOR(), DATA_PATH(), int($&)); - } - elsif ($f =~ /^(c(frt)?)|(noaccess)$/) { # CFRT (no access) - $file = DATA_NOACCESS_PATH(); - } - elsif ($f =~ /^d(efault)?$/) { # default - $file = DATA_DEFAULT_PATH(); - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_DEFAULT_PATH(); - } - - %data = read_data_file($file); - if (ref ($default)) { - %data = merge_settings($default, \%data); - } - elsif ($default ne '') { - my %default_data = read_data_file(DATA_DEFAULT_PATH()); - %data = merge_settings(\%default_data, \%data); - } - - return validate_frame_data(\%data); -} - -sub write_frame_data { - (my $f, my $data) = @_; - my $file; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # frame ID - $file = join_path(PATH_SEPARATOR(), DATA_PATH(), int($&)); - } - elsif ($f =~ /^(c(frt)?)|(noaccess)$/) { # CFRT (no access) - return 0; # forbidden - } - elsif ($f =~ /^d(efault)?$/) { # default - return 0; # forbidden - } - elsif ($f ne '') { # path - $file = $f; - } - else { - return 0; # forbidden - } - - my %_data = validate_frame_data($data); - - return write_data_file($file, \%_data); -} - -sub read_default { - return read_frame_data('default'); -} - -sub read_noaccess { - (my $default) = @_; - return read_frame_data('noaccess', $default); -} - -sub read_settings { - (my $f) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_SETTINGS_PATH(); - } - - %data = read_data_file($file); - - return validate_settings(\%data); -} - -sub read_state { - (my $f) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_STATE_PATH(); - } - - %data = read_data_file($file); - - return validate_state(\%data); -} - -sub write_state { - (my $f, my $data) = @_; - my $file; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = PERL_DATA_STATE_PATH(); - } - - my %_data = validate_state($data); - - return write_data_file($file, \%_data); -} - -sub read_words_list { - (my $f, my $header_only, my $not_list) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # frame ID - $file = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), int($&)); - } - elsif ($f ne '') { # path - $file = $f; - } - else { # which frame ??? - return ('posts' => 0); - } - - %data = read_data_file( - $file, - '', # encoding - 0, # no header - $header_only, - not $not_list # as list - ); - - return validate_words_list(\%data, $not_list); -} - -sub write_words_list { - (my $f, my $data) = @_; - my $file; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # frame ID - $file = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), int($&)); - } - elsif ($f ne '') { # path - $file = $f; - } - else { # which frame ??? - return 0; - } - - my %_data = validate_words_list($data); - - return write_data_file( - $file, # file - \%_data, - '', # encoding - 0, # no header - 0, # header only - 1 # as list - ); -} - -sub read_words { - (my $f, my $default) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+\.[0-9\.]+$/) { # post ID - $file = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $&); - } - elsif ($f ne '') { # path - $file = $f; - } - else { # which post ??? - return (); - } - - %data = read_data_file($file); - - return validate_words(\%data); -} - -sub write_words { - (my $f, my $data) = @_; - my $file; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9\.]+$/) { # post ID - $file = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $&); - } - elsif ($f ne '') { # path - $file = $f; - } - else { # which post ??? - return 0; - } - - my %_data = validate_words($data); - - return write_data_file($file, \%_data); -} - -sub read_story { - (my $f) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # story ID - $file = DATA_STORY_PATH().int($&); - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_STORY_PATH(); - } - - %data = read_data_file($file); - - return validate_story(\%data); -} - -sub write_story { - (my $f, my $data) = @_; - my $file; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # story ID - $file = DATA_STORY_PATH().int($&); - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_STORY_PATH(); - } - - my %_data = validate_story($data); - - return write_data_file($file, \%_data); -} - -sub read_goto { - (my $f) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_LIST_PATH(); - } - - %data = read_data_file($file); - - return validate_goto(\%data); -} - -sub write_goto { - (my $f, my $data) = @_; - my $file; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_LIST_PATH(); - } - - my %_data = validate_goto($data); - - return write_data_file($file, \%_data); -} - -sub read_attachment { - (my $f, my $default) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # attachment ID - $file = DATA_ATTACH_PATH().int($&); - } - elsif ($f ne '') { # path - $file = $f; - } - else { - return (); - } - - %data = read_data_file($file); - - return validate_attachment(\%data); -} - -sub read_coincidence { - (my $f) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_COIN_PATH(); - } - - %data = read_data_file($file); - - return validate_coincidence(\%data); -} - -sub read_chat { - (my $f) = @_; - my $file; - my %data; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # chat ID - $file = DATA_CHAT_PATH().int($&); - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_CHAT_PATH(); - } - - return read_data_file($file); - - # no validation -} - -sub write_chat { - (my $f, my $data) = @_; - my $file; - - if (ref ($f)) { # already open file - $file = $f; - } - elsif ($f =~ /^[0-9]+$/) { # chat ID - $file = DATA_CHAT_PATH().int($&); - } - elsif ($f ne '') { # path - $file = $f; - } - else { - $file = DATA_CHAT_PATH(); - } - - # no validation - - return write_data_file($file, $data); -} - - -1 diff --git a/chat.1.pl b/chat.1.pl deleted file mode 100644 index 90ea637..0000000 --- a/chat.1.pl +++ /dev/null @@ -1,507 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/coin -# chat.pl is generated from chat.1.pl. -# -# The coincidence interface -# -# Copyright (C) 2016, 2017, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -###PERL_LIB: use lib /botm/lib/bsta -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'read_header_env', - 'url_query_decode', 'url_query_encode', - 'merge_url', - 'html_entity_encode_dec', - 'open_encoded', - 'http_header_status' -); -use bsta_lib ( - 'STATE', 'CHAT_STATE', 'CHAT_ACTION', - 'fail_method', 'fail_content_type', - 'get_remote_addr', 'get_id', 'get_password', - 'print_html_start', 'print_html_end', - 'print_html_head_start', 'print_html_head_end', - 'print_html_body_start', 'print_html_body_end', - 'merge_settings', - 'read_chat', 'write_chat', - 'read_coincidence', 'read_settings', 'read_state' -); -use File::Copy; - -###PERL_CGI_PATH: CGI_PATH = /bsta/ -###PERL_CGI_COIN_PATH: CGI_COIN_PATH = /bsta/coin - -###PERL_DATA_CHAT_PATH: DATA_CHAT_PATH = /botm/data/bsta/chat - -###PERL_WEBSITE_NAME: WEBSITE_NAME = Bicycles on the Moon - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my %http; -my %cgi; -my %coin; -my %chat; -my %settings; -my %state; - -my $time = time(); -srand ($time-$$); - -my $method; -my $IP; -my $page; -my $words = ''; -my $username = ''; -my $action = CHAT_ACTION->{'none'}; -my $password; -my $fh; -my $state; -my $password_ok; -my @chat_lines; -my $chat_state; -my $status; -my $message; -my $chat_id; -my $last_id; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else { - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else{ - exit fail_content_type($method, $http{'content-type'}); - } -} - -$IP = get_remote_addr(); -$page = get_id(\%cgi, -1); -$password = get_password(\%cgi); - -%coin = read_coincidence(); -%settings = read_settings(); -%state = read_state(); - -$password_ok = ($password eq $settings{'password'}); - -if ($cgi{'words'} ne '') { - $words = $cgi{'words'}; -} -if ($password_ok && ($cgi{'username'} ne '')) { - $username = $cgi{'username'}; -} -foreach my $action_id ('join', 'leave', 'nopost', 'file') { - if ($cgi{$action_id} ne '') { - $action = CHAT_ACTION->{$action_id}; - last; - } -} - -# ongoing chat -if ($page < 0) { - if (open_encoded($fh, "+<", DATA_CHAT_PATH())) { - if (flock($fh, 2)) { - %chat = read_chat($fh); - - $chat_state = int($chat{'state'}); - $chat_id = int($chat{'id'}); - $last_id = $chat_id; - - if ($method ne 'POST') { - # - } - - elsif ( - ($action == CHAT_ACTION->{'none'}) && - ($words ne '') - ) { - if (($chat_state < CHAT_STATE->{'ready'}) && !$password_ok) { - $status = HTTP_STATUS->{'forbidden'}; - $message = 'Not connected.'; - } - else { - if ($words !~ /[\r\n]/) { - if ($username =~ /^[A-Za-z]*$/) { - $chat{'content'} .= $username.': '.$words."\n"; - if ($chat_state < CHAT_STATE->{'active'}) { - $chat_state = CHAT_STATE->{'active'}; - $chat{'state'} = $chat_state; - } - write_chat($fh, \%chat); - } - else { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Invalid username.'; - } - } - else { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Invalid text.'; - } - } - } - - elsif ($action == CHAT_ACTION->{'join'}) { - if (($chat_state > CHAT_STATE->{'disconnected'}) && !$password_ok) { - $message = 'Already connected.'; - } - else { - if ($username =~ /^[A-Za-z]*$/) { - if ($password_ok || $words eq $coin{'server'}) { - $chat{'content'} .= 'join@'.$username.': '.$words."\n"; - if ($chat_state < CHAT_STATE->{'ready'}) { - $chat_state = CHAT_STATE->{'ready'}; - $chat{'state'} = $chat_state; - } - write_chat($fh, \%chat); - } - elsif ($words eq '') { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Server ID missing.'; - } - elsif ($words !~ /^[0-9]+$/) { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Invalid server ID.'; - } - else { - $status = HTTP_STATUS->{'not_found'}; - $message = 'No active Coincidence server with this ID.'; - } - } - else { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Invalid username.'; - } - } - } - - elsif ($action == CHAT_ACTION->{'leave'}) { - if (($chat_state < CHAT_STATE->{'ready'}) && !$password_ok) { - $message = 'Already disconnected.'; - } - else { - if ($username =~ /^[A-Za-z]*$/) { - $chat{'content'} .= 'leave@'.$username.': '.$words."\n"; - if ($username ne '') { - write_chat($fh, \%chat); - } - else { - my %new_chat; - if ($chat_state > 1) { - write_chat($chat_id, \%chat); - $new_chat{'id'} = $chat_id+1; - } - else { - $new_chat{'id'} = $chat_id; - } - $new_chat{'state'} = CHAT_STATE->{'disconnected'}; - $new_chat{'content'} = ''; - write_chat($fh, \%new_chat); - } - } - else { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Invalid username.'; - } - } - } - - elsif ( - ($action == CHAT_ACTION->{'file'}) && - ($cgi{'file'} ne '') && - ($words ne '') && - $password_ok - ) { - if ($words !~ /[\r\n]/) { - if ($username =~ /^[A-Za-z]*$/) { - $chat{'content'} .= 'file@'.$username.': '.$words."\n"; - if ($chat_state < CHAT_STATE->{'active'}) { - $chat_state = CHAT_STATE->{'active'}; - $chat{'state'} = $chat_state; - } - write_chat($fh, \%chat); - } - else { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Invalid username.'; - } - } - else { - $status = HTTP_STATUS->{'bad_request'}; - $message = 'Invalid text.'; - } - } - - @chat_lines = split(/\r?\n/, $chat{'content'}); - } - else { - $chat_state = CHAT_STATE->{'disconnected'}; - $status = HTTP_STATUS->{'internal_server_error'}; - $message = 'Can\'t lock data file!'; - } - - close($fh); - } - else { - $chat_state = CHAT_STATE->{'disconnected'}; - $status = HTTP_STATUS->{'internal_server_error'}; - $message='Can\'t open data file!'; - } -} -# old chat archive -else { - $chat_id = $page; - %chat = read_chat(); - $last_id = int($chat{'id'}); - if ($chat_id < $last_id) { - %chat = read_chat($page); - $chat_state = int($chat{'state'}); - @chat_lines = split(/\r?\n/, $chat{'content'}); - } -} - -if ($status ne '') { - print http_header_status($status); -} -print "Content-type: text/html; charset=UTF-8\n\n"; -if($method eq 'HEAD') { - exit; -} - -if ($username eq '') { - $username = $coin{'name'}; -} - -my $base_url = CGI_PATH(); -my $coin_url = CGI_COIN_PATH(); -my $form_url = $coin_url; -my $oldest_url = merge_url( - {'path' => $coin_url}, - {'path' => 0} -); -my $older_url = merge_url( - {'path' => $coin_url}, - {'path' => $chat_id -1} -); -my $newer_url = ($chat_id < ($last_id -1)) ? - merge_url( - {'path' => $coin_url}, - {'path' => $chat_id +1} - ) : $coin_url; - -if ($password_ok) { - my $password_query = url_query_encode({'p', $settings{'password'}}); - $coin_url = merge_url($coin_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $oldest_url = merge_url($oldest_url, {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $older_url = merge_url($older_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); - $newer_url = merge_url($newer_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 1}); -} - -my $_password = $password_ok ? html_entity_encode_dec($settings{'password'}, 1): ''; -my $abbr = abbr_name($username); -my $_website_name = html_entity_encode_dec(WEBSITE_NAME() , 1); -my $_server = html_entity_encode_dec($coin {'server'} , 1); -my $_key = html_entity_encode_dec($coin {'key'} , 1); -my $_cgi_username = html_entity_encode_dec($cgi {'username'}, 1); -my $_username = html_entity_encode_dec($username , 1); -my $_abbr = html_entity_encode_dec($abbr , 1); -my $_message = html_entity_encode_dec($message , 1); -my $_base_url = html_entity_encode_dec($base_url , 1); -my $_coin_url = html_entity_encode_dec($coin_url , 1); -my $_form_url = html_entity_encode_dec($form_url , 1); -my $_oldest_url = html_entity_encode_dec($oldest_url, 1); -my $_older_url = html_entity_encode_dec($older_url , 1); -my $_newer_url = html_entity_encode_dec($newer_url , 1); - -print_html_start(\*STDOUT); -print_html_head_start(\*STDOUT); - -print ' Coincidence • '.$_website_name.''."\n"; - -print_html_head_end(\*STDOUT); -print_html_body_start(\*STDOUT); - -print '
    '."\n"; - -print '
    '."\n"; -print '

    Coincidence

    '."\n"; -print '
    '."\n"; - -print '
    '."\n"; -if ($page >= 0) { - print ' Before: '.$chat_id."\n"; -} -elsif ($chat_state > CHAT_STATE->{'disconnected'}) { - print ' Connected to server '.$_server.' as user '.$_username.' ('.$_abbr.'), public key '.$_key.'.'."\n"; -} -else{ - print ' Not connected.'."\n"; -} -print '
    '."\n"; - -print '
    '."\n"; -if ($message ne '') { - print ' '.$_message.''."\n"; -} -if ($page < 0) { - print '
    '."\n"; - if ($password_ok) { - print ' '."\n"; - print ' '."\n"; - print " |\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - } - elsif ($chat_state > CHAT_STATE->{'disconnected'}) { - print ' '."\n"; - print ' '."\n"; - print " |\n"; - print ' '."\n"; - print ' '."\n"; - } - else { - print ' '."\n"; - print ' '."\n"; - } - print '
    '."\n"; -} -print '
    '."\n"; - -print '
    '."\n"; -print '
    '."\n"; - -print '
    '."\n"; -if ($page < 0) { - for (my $i = @chat_lines-1; $i>=0; --$i) { - print ' '.chat_line($chat_lines[$i])."
    \n"; - } -} -else { - for (my $i = 0; $i<@chat_lines; ++$i) { - print ' '.chat_line($chat_lines[$i])."
    \n"; - } -} -print '
    '."\n"; - -print ' '."\n"; - -print '
    '."\n"; - -print_html_body_end(\*STDOUT, int($state{'state'}) == STATE->{'inactive'}); -print_html_end(\*STDOUT); - - -sub abbr_name { - (my $name) = @_; - my $abbr; - - if($name !~ /^[A-Za-z]+$/) { - return '?'; - } - - $abbr = uc(substr($name,0,1)); - $name = substr($name,1); - while($name =~ m/([A-Z])/g) { - $abbr = $abbr.$1; - } - return $abbr; -} - -sub chat_line { - (my $line) = @_; - - if ($line =~ /^([a-z]*@)?([A-Za-z]*): (.*)$/) { - my $action = $1; - my $name = $2; - my $text = $3; - my $color; - if ($name eq '') { - $name = $coin{'name'}; - $color = 'ni'; - } - else { - $color = 'br'; - } - $abbr = abbr_name($name); - - my $_name = html_entity_encode_dec($name , 1); - my $_abbr = html_entity_encode_dec($abbr , 1); - my $_text = html_entity_encode_dec($text , 1); - my $_server = html_entity_encode_dec($coin{'server'}, 1); - - if($action ne '') { - if ($action eq 'join@') { - return "$_name ($_abbr) joined the public chat on server $_server."; - } - elsif ($action eq 'leave@') { - return "$_name ($_abbr) left the public chat on server $_server."; - } - elsif ($action eq 'file@') { - return "$_name ($_abbr) sent the file $_text."; - } - else { - return 'E:E:E'; - } - } - else { - return "$_abbr: $_text"; - } - } - else { - return 'E:E:E'; - } -} diff --git a/exec b/exec deleted file mode 160000 index 92cf35c..0000000 --- a/exec +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 92cf35c0340afcadb39f06248de26e114ad5603c diff --git a/frame.1.pl b/frame.1.pl deleted file mode 100644 index a0a81fd..0000000 --- a/frame.1.pl +++ /dev/null @@ -1,206 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/f -# viewer.pl is generated from viewer.1.pl. -# -# The frame interface -# -# Copyright (C) 2016, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'read_header_env', - 'url_query_decode', - 'join_path', - 'merge_url', - 'open_encoded', 'stat_encoded', - 'http_header_line', 'http_header_content_length', 'http_header_content_disposition' -); -use bsta_lib ( - 'STATE', 'INTF_STATE', - 'fail_method', 'fail_content_type', 'fail_open_file', 'fail_500', 'redirect', - 'get_frame', 'get_password', - 'merge_settings', - 'get_frame_file', - 'read_frame_data', 'read_default', 'read_noaccess', - 'read_settings', 'read_state', 'read_story' -); - -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_CGI_PATH: CGI_PATH = /bsta/ -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta -###PERL_WWW_PATH: WWW_PATH = /botm/www/1190/bsta/ - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my $time = time(); -srand ($time-$$); - -my %http; -my %cgi; -my %frame_data; -my %default; -my %settings; -my %state; - -my $method; -my $frame; -my $password; -my $password_ok; -my $IP; -my $access; -my $try_onged; -my $frame_path; -my $frame_file; -my $fh; -my $buffer; -my $ong_state; -my $last_frame; -my $r = 0; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else{ - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else{ - exit fail_content_type($method, $http{'content-type'}); - } -} - -$frame = get_frame(\%cgi); -$password = get_password(\%cgi); - -%settings = read_settings(); -%default = read_default(); -%state = read_state(); - -$ong_state = int($state{'state'}); -$last_frame = int($state{'last'}); - -if ($frame < 0) { - $frame = $state{'last'} + $frame +1; -} - -$password_ok = ($password eq $settings{'password'}); - -$access = 0; -if ( - $password_ok || ( - ($ong_state >= STATE->{'waiting'}) && - ($frame <= $last_frame) && - ($frame >= 0) - ) - ) { - $access = 1; -} -elsif ( - ($ong_state == STATE->{'inactive'}) && - ($frame == 0) -) { - my %story = read_story(); - if ( - (int($story{'pass'}) == 1) && - (int($story{'state'}) == INTF_STATE->{'>|'}) - ) { - $access = 1; - } -} - -$try_onged = ( - (!$access) || ( - ($frame <= $last_frame) && - ($ong_state > STATE->{'inactive'}) - ) -); - -if ($access) { - %frame_data = read_frame_data($frame, \%default); -} -else { - %frame_data = read_noaccess(\%default); -} -$frame_file = get_frame_file($frame, \%frame_data, \%settings); - -if ($try_onged) { - $frame_path = join_path(PATH_SEPARATOR(), WWW_PATH(), $frame_file); - $r = open_encoded($fh, '<' , $frame_path); - if ($r) { - close($r); - $frame_path = merge_url( - {'path' => CGI_PATH()}, - {'path' => $frame_file} - ); - exit redirect ($method, $frame_path, HTTP_STATUS->{'see_other'}); - } -} -unless ($r) { - $frame_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame_file); - $r = open_encoded($fh, '<' , $frame_path); - unless ($r) { - exit fail_open_file($method, 'image file', $frame_file); - } -} -unless (binmode($fh)) { - close($fh); - exit fail_500("Can't switch file to binary mode."); -} - -if (my @file_info = stat_encoded($frame_path)){ - print http_header_content_length($file_info[7]); -} -if ($frame_data{'content-type'} ne '') { - print http_header_line('content-type', $frame_data{'content-type'}); -} -if ($frame_file ne '') { - print http_header_content_disposition('inline', $frame_file); -} -unless (binmode STDOUT) { - close($fh); - exit fail_500("Can't switch output to binary mode."); -} -print "\n"; - -if($method ne 'HEAD'){ - while (read ($fh, $buffer, 1024)) { - print (STDOUT $buffer); - } -} -close($fh); diff --git a/goto.1.pl b/goto.1.pl deleted file mode 100644 index 37feb23..0000000 --- a/goto.1.pl +++ /dev/null @@ -1,123 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/g -# goto is generated from goto.1.pl. -# -# The frame list -# -# Copyright (C) 2017, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'read_header_env', - 'url_query_decode', - '_x_encoded' -); -use bsta_lib ( - 'STATE', - 'fail_method', 'fail_content_type', - 'redirect', - 'get_password', - 'print_goto', - 'merge_settings', - 'read_settings', 'read_state', 'read_goto' -); - -###PERL_CGI_PATH: CGI_PATH = /bsta/ -###PERL_CGI_LIST_PATH: CGI_LIST_PATH = /bsta/goto.htm -###PERL_CGI_VIEWER_PATH: CGI_VIEWER_PATH = /bsta/v - -###PERL_WWW_GOTO_PATH: WWW_GOTO_PATH = /botm/www/1190/bsta/goto.htm - -###PERL_WEBSITE_NAME: WEBSITE_NAME = Bicycles on the Moon - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my $time = time(); -srand ($time-$$); - -my %http; -my %cgi; -my %settings; -my %state; -my %goto_list; - -my $method; -my $password; -my $password_ok; -my $no_cgi; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else{ - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else{ - exit fail_content_type($method, $http{'content-type'}); - } -} - -$no_cgi = (scalar (keys %cgi) == 0); - -if ($no_cgi) { - if (_x_encoded('-f', WWW_GOTO_PATH())) { - exit redirect($method, CGI_LIST_PATH()); - } -} - -$password = get_password(\%cgi); - -%settings = read_settings(); -%state = read_state(); -%goto_list = read_goto(); - -$password_ok = ($password eq $settings{'password'}); - -print "Content-type: text/html; charset=UTF-8\n"; -print "\n"; -if($method eq 'HEAD') { - exit; -} - -print_goto( - \*STDOUT, - \%state, - \%settings, - \%goto_list, - $password_ok -); diff --git a/info.1.pl b/info.1.pl deleted file mode 100644 index 3778092..0000000 --- a/info.1.pl +++ /dev/null @@ -1,263 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/i -# info.pl is generated from info.1.pl. -# -# The frame/story info interface -# -# Copyright (C) 2017, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'http_header_status', - 'read_header_env', - 'write_data_file', - 'url_query_decode' -); -use bsta_lib ( - 'STATE', - 'fail_method', 'fail_content_type', - 'get_password', - 'merge_settings', - 'get_page_file', 'get_frame_file', - 'read_frame_data', 'read_default', 'read_noaccess', - 'read_settings', 'read_default', 'read_state', - 'read_words_list', 'read_words', 'read_attachment' -); - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my $time = time(); -srand ($time-$$); - -my %http; -my %cgi; -my %info_data; -my %next_frame_data; -my %default; -my %settings; -my %state; - -my $method; -my $frame = ''; -my $attachment = ''; -my $words = ''; -my $password; -my $password_ok; -my $access; -my $show_command; -my $ongtime; -my $timer; -my $ong_state; -my $last_frame; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else{ - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else{ - exit fail_content_type($method, $http{'content-type'}); - } -} - -if ($cgi{'f'} =~ /^.+$/) { - $frame = int($&); -} -elsif ($cgi{'a'} =~ /^.+$/) { - $attachment = int($&); -} -elsif ($cgi{'i'} =~ /^.+$/) { - $attachment = int($&); -} -elsif ($cgi{'w'} =~ /^.+$/) { - $words = $&; -} -elsif ($ENV{'PATH_INFO'} =~ /^\/a\/?(.+)$/) { - $attachment = int($1); -} -elsif ($ENV{'PATH_INFO'} =~ /^\/w\/?(.+)$/) { - $words = $1; -} -elsif ($ENV{'PATH_INFO'} =~ /^\/(f\/?)?(.+)$/) { - $frame = int($2); -} - -$password = get_password(\%cgi); - -%settings = read_settings(); -%default = read_default(); -%state = read_state(()); - -$ong_state = int($state{'state'}); -$last_frame = int($state{'last'}); - -$password_ok = ($password eq $settings{'password'}); - -# comment info, not frame -if ($words ne '') { - if ($words =~ /^[0-9]+$/) { - %info_data = read_words_list( - int($&), # id - 0, # header only - 1 # not as list - ); - $frame = int($&); - if ($info_data{'posts'} eq '') { - $info_data{'posts'} = 0; - } - } - elsif ($words =~ /^[0-9]+\.[0-9\.]+$/) { - %info_data = read_words($&); - $frame = ($info_data{'frame'} ne '') ? int($info_data{'frame'}) : -1; - unless ($password_ok) { - delete($info_data{'password'}); - delete($info_data{'key'}); - } - } -} -# attachment info, not frame -elsif ($attachment ne '') { - %info_data = read_attachment($attachment); - $frame = ($info_data{'frame'} ne '') ? int($info_data{'frame'}) : -1; -} -# frame info -elsif ($frame ne '') { - if ($frame < 0) { - $frame = $last_frame + $frame +1; - } - %info_data = read_frame_data($frame, \%default); - %next_frame_data = read_frame_data($frame+1, \%default); - - $timer = int($state{'nextong'}) - $time; - $ongtime = int($state{'ongtime'}); - if($ongtime == 0) { - $ongtime = int($settings{'ongtime'}) - } - $show_command = ($timer < ($ongtime * 3600 / 3)); -} -# state info, not frame -else { - unless ($password_ok) { - # just show if IP was saved, not its value - if ($state{'ip1'} ne '') { - $state{'ip1'} = 1; - } - if ($state{'ip2'} ne '') { - $state{'ip2'} = 1; - } - if ($state{'ip3'} ne '') { - $state{'ip3'} = 1; - } - } - print "Content-type: text/plain; charset=UTF-8\n\n"; - if ($method eq 'HEAD') { - exit; - } - write_data_file( - \*STDOUT, \%state, '', - 0, 0, 0, - '>>', 1 - ); - - exit; -} - -if ( - $password_ok || ( - ($ong_state >= STATE->{'waiting'}) && - ($frame <= $last_frame) && - ($frame >= 0) - ) -) { - $access = 1; - - if ( - ($words eq '') && - ($attachment eq '') && - ($info_data{'command'} eq '') && ( - $password_ok || - ($frame < $last_frame) || ( - ($ong_state >= STATE->{'ready'}) && - $show_command - ) - ) - ) { - $info_data{'command'} = $next_frame_data{'title'}; - } -} -else { - $access = 0; - if (($attachment ne '') || ($words ne '')) { - %info_data = (); - } - else { - %info_data = read_noaccess(\%default); - } -} -if ( - ($attachment eq '') && - ($words eq '') -) { - if ($info_data{'frame'} eq '') { - $info_data{'frame'} = get_frame_file($frame, \%info_data, \%settings) - } - if ($info_data{'page'} eq '') { - unless (($access) && ($frame < $last_frame)) { - $info_data{'page'} = ''; - } - else { - $info_data{'page'} = get_page_file($frame, \%info_data, \%settings); - } - } -} - -print "Content-type: text/plain; charset=UTF-8\n"; -if (!$access) { - print http_header_status(HTTP_STATUS->{'forbidden'}); -} -print "\n"; -if($method eq 'HEAD') { - exit; -} -write_data_file( - \*STDOUT, \%info_data, '', - 0, 0, 0, - '>>', 1 -); diff --git a/install.sh b/install.sh index 22a4f9e..27f5a30 100755 --- a/install.sh +++ b/install.sh @@ -1,8 +1,5 @@ #!/bin/sh make clean -make -B TARGET=bsta makefile -make install -make clean -make -B TARGET=again makefile +make -B TARGET=release makefile make install make clean diff --git a/makefile b/makefile index 7007b12..f702897 100644 --- a/makefile +++ b/makefile @@ -23,26 +23,15 @@ TARGET = debug endif PERL = perl -CC =/usr/bin/gcc -CF =-g -Wall - CHMOD=/usr/bin/chmod CP =/usr/bin/cp MKDIR=/usr/bin/mkdir PERL =/usr/bin/perl RM =/usr/bin/rm -SUDO =/usr/bin/sudo -BIN_PATH = /botm/bin/test-bsta -DATA_PATH = /botm/data/test-bsta -DATA_WORDS_PATH = /botm/data/test-bsta/words -LIB_PATH = /botm/lib/test-bsta -LOG_PATH = /botm/log/test-bsta -TMP_PATH = /botm/tmp/test-bsta -WWW_PATH = /botm/www/1190/bstatest +BIN_PATH = /botm/bin/test-oldlogs +LIB_PATH = /botm/lib/test-oldlogs -CONF = /botm/etc/www/conf/1190/test-bsta.conf -CRON = /etc/cron.d/test-bsta CONFIGFILE = settings-$(TARGET).txt settings.txt DEFAULT_CONFIGFILE = settings-$(DEFAULT_TARGET).txt settings.txt @@ -52,107 +41,31 @@ CONFIGURE_CMD = $(PERL) ./configure.pl $(CONFIGFILE) # keep these 2 lists in the same order!: GENERATE_FROM=\ -2words.1.pl\ -attach.1.pl\ -bbcode.1.pl\ -bsta.1.conf\ -bsta.1.cron\ -bsta_lib.1.pm\ -chat.1.pl\ -frame.1.pl\ -goto.1.pl\ -info.1.pl\ -oldlogs.1.pl\ -opomba.1.pl\ -ong.1.pl\ -reset.1.pl\ -update.1.pl\ -viewer.1.pl +oldlogs.1.pl TO_GENERATE=\ -2words.pl\ -attach.pl\ -bbcode.pl\ -bsta.conf\ -bsta.cron\ -bsta_lib.pm\ -chat.pl\ -frame.pl\ -goto.pl\ -info.pl\ -oldlogs.pl\ -opomba.pl\ -ong.pl\ -reset.pl\ -update.pl\ -viewer.pl +oldlogs.pl DIR=\ $(BIN_PATH)\ -$(DATA_PATH)\ -$(DATA_WORDS_PATH)\ -$(LIB_PATH)\ -$(LOG_PATH)\ -$(TMP_PATH)\ -$(WWW_PATH) - -HIDDEN_DIR=\ -$(DATA_PATH)\ -$(DATA_WORDS_PATH)\ -$(TMP_PATH) - -SETUID=\ -2words\ -bbcode\ -attach\ -chat\ -frame\ -goto\ -info\ -opomba\ -viewer +$(LIB_PATH) + +# HIDDEN_DIR= + +# SETUID= EXEC=\ -2words.pl\ -attach.pl\ -bbcode.pl\ -chat.pl\ -frame.pl\ -goto.pl\ -info.pl\ -oldlogs.pl\ -opomba.pl\ -ong.pl\ -reset.pl\ -update.pl\ -viewer.pl - -PERL_WRAP_EXEC=\ -2words\ -attach\ -bbcode\ -chat\ -frame\ -goto\ -info\ -opomba\ -viewer +oldlogs.pl + +# PERL_WRAP_EXEC= BIN=\ -$(EXEC)\ -$(PERL_WRAP_EXEC) +$(EXEC) LIB=\ botm-common/botm_common.pm\ -bsta_lib.pm - -WWW=\ -botmlogo.png\ -bsta.css\ -timer.js - -all: $(BIN) setuid exec +all: $(BIN) exec makefile: makefile.1.mak $(CONFIGFILE) configure.pl @@ -164,25 +77,15 @@ configure.pl: $(CONFIGFILE) config/configure.1.pl $(TO_GENERATE): $(GENERATE_FROM) $(CONFIGFILE) configure.pl $(CONFIGURE_CMD) --in $(GENERATE_FROM) --out $(TO_GENERATE) -$(PERL_WRAP_EXEC): %: exec/exec.c exec/settings.txt configure.pl - $(PERL) configure.pl path=$(BIN_PATH) target=$*.pl io_path=$(LOG_PATH) stderr=$*-stderr.log exec/settings.txt --in exec/exec.c --out $*.c - $(CC) $(CF) -o $@ $*.c - exec: $(EXEC) $(CHMOD) +x $(EXEC) -wrap_exec: - -setuid: $(SETUID) - $(CHMOD) u+s,g+s $(SETUID) - - mktree: $(MKDIR) -p $(DIR) - $(CHMOD) g-r,g-w,g-x,o-r,o-w,o-x $(HIDDEN_DIR) +# $(CHMOD) g-r,g-w,g-x,o-r,o-w,o-x $(HIDDEN_DIR) ifdef BIN_PATH -cp_bin: $(BIN) setuid exec | mktree +cp_bin: $(BIN) exec | mktree $(RM) -f $(BIN_PATH)/* $(CP) -p $(BIN) $(BIN_PATH) endif @@ -193,21 +96,13 @@ cp_lib: $(LIB) | mktree $(CP) -p $(LIB) $(LIB_PATH) endif -cp_www: - $(CP) -p $(WWW) $(WWW_PATH) - -cp_conf: bsta.conf - $(CP) bsta.conf $(CONF) - -cp_cron: bsta.cron - $(SUDO) $(CP) bsta.cron $(CRON) -install: all cp_bin cp_lib cp_www cp_conf cp_cron +install: all cp_bin cp_lib clean: - $(RM) -f configure.pl $(TO_GENERATE) $(PERL_WRAP_EXEC) $(PERL_WRAP_EXEC:=.c) + $(RM) -f configure.pl $(TO_GENERATE) $(PERL) config/configure.1.pl $(DEFAULT_CONFIGFILE) < makefile.1.mak > makefile -PHONY: all clean install setuid exec mktree cp_bin cp_lib cp_www cp_conf cp_cron +PHONY: all clean install exec mktree cp_bin cp_lib diff --git a/makefile.1.mak b/makefile.1.mak index 7ff6c93..496f8cf 100644 --- a/makefile.1.mak +++ b/makefile.1.mak @@ -23,26 +23,15 @@ TARGET = $(DEFAULT_TARGET) ###MAKE_TARGET: endif PERL = perl -###MAKE_CC: CC=gcc -###MAKE_CF: CF=-g -Wall - ###MAKE_CHMOD: CHMOD = chmod ###MAKE_CP: CP = cp ###MAKE_MKDIR: MKDIR = mkdir ###MAKE_PERL: PERL = perl ###MAKE_RM: RM = rm -###MAKE_SUDO: SUDO = sudo ###MAKE_BIN_PATH: BIN_PATH = /botm/bin/bsta -###MAKE_DATA_PATH: DATA_PATH = /botm/data/bsta -###MAKE_DATA_WORDS_PATH: DATA_WORDS_PATH = /botm/data/bsta/words ###MAKE_LIB_PATH: LIB_PATH = /botm/lib/bsta -###MAKE_LOG_PATH: LOG_PATH = /botm/log/bsta -###MAKE_TMP_PATH: TMP_PATH = /botm/tmp/bsta -###MAKE_WWW_PATH: WWW_PATH = /botm/www/1190/bsta -###MAKE_CONF: CONF = /botm/etc/www/conf/1190/bsta.conf -###MAKE_CRON: CRON = /etc/cron.d/bsta CONFIGFILE = settings-$(TARGET).txt settings.txt DEFAULT_CONFIGFILE = settings-$(DEFAULT_TARGET).txt settings.txt @@ -52,107 +41,31 @@ CONFIGURE_CMD = $(PERL) ./configure.pl $(CONFIGFILE) # keep these 2 lists in the same order!: GENERATE_FROM=\ -2words.1.pl\ -attach.1.pl\ -bbcode.1.pl\ -bsta.1.conf\ -bsta.1.cron\ -bsta_lib.1.pm\ -chat.1.pl\ -frame.1.pl\ -goto.1.pl\ -info.1.pl\ -oldlogs.1.pl\ -opomba.1.pl\ -ong.1.pl\ -reset.1.pl\ -update.1.pl\ -viewer.1.pl +oldlogs.1.pl TO_GENERATE=\ -2words.pl\ -attach.pl\ -bbcode.pl\ -bsta.conf\ -bsta.cron\ -bsta_lib.pm\ -chat.pl\ -frame.pl\ -goto.pl\ -info.pl\ -oldlogs.pl\ -opomba.pl\ -ong.pl\ -reset.pl\ -update.pl\ -viewer.pl +oldlogs.pl DIR=\ $(BIN_PATH)\ -$(DATA_PATH)\ -$(DATA_WORDS_PATH)\ -$(LIB_PATH)\ -$(LOG_PATH)\ -$(TMP_PATH)\ -$(WWW_PATH) - -HIDDEN_DIR=\ -$(DATA_PATH)\ -$(DATA_WORDS_PATH)\ -$(TMP_PATH) - -SETUID=\ -2words\ -bbcode\ -attach\ -chat\ -frame\ -goto\ -info\ -opomba\ -viewer +$(LIB_PATH) + +# HIDDEN_DIR= + +# SETUID= EXEC=\ -2words.pl\ -attach.pl\ -bbcode.pl\ -chat.pl\ -frame.pl\ -goto.pl\ -info.pl\ -oldlogs.pl\ -opomba.pl\ -ong.pl\ -reset.pl\ -update.pl\ -viewer.pl - -PERL_WRAP_EXEC=\ -2words\ -attach\ -bbcode\ -chat\ -frame\ -goto\ -info\ -opomba\ -viewer +oldlogs.pl + +# PERL_WRAP_EXEC= BIN=\ -$(EXEC)\ -$(PERL_WRAP_EXEC) +$(EXEC) LIB=\ botm-common/botm_common.pm\ -bsta_lib.pm - -WWW=\ -botmlogo.png\ -bsta.css\ -timer.js - -all: $(BIN) setuid exec +all: $(BIN) exec makefile: makefile.1.mak $(CONFIGFILE) configure.pl @@ -164,25 +77,15 @@ configure.pl: $(CONFIGFILE) config/configure.1.pl $(TO_GENERATE): $(GENERATE_FROM) $(CONFIGFILE) configure.pl $(CONFIGURE_CMD) --in $(GENERATE_FROM) --out $(TO_GENERATE) -$(PERL_WRAP_EXEC): %: exec/exec.c exec/settings.txt configure.pl - $(PERL) configure.pl path=$(BIN_PATH) target=$*.pl io_path=$(LOG_PATH) stderr=$*-stderr.log exec/settings.txt --in exec/exec.c --out $*.c - $(CC) $(CF) -o $@ $*.c - exec: $(EXEC) $(CHMOD) +x $(EXEC) -wrap_exec: - -setuid: $(SETUID) - $(CHMOD) u+s,g+s $(SETUID) - - mktree: $(MKDIR) -p $(DIR) - $(CHMOD) g-r,g-w,g-x,o-r,o-w,o-x $(HIDDEN_DIR) +# $(CHMOD) g-r,g-w,g-x,o-r,o-w,o-x $(HIDDEN_DIR) ifdef BIN_PATH -cp_bin: $(BIN) setuid exec | mktree +cp_bin: $(BIN) exec | mktree $(RM) -f $(BIN_PATH)/* $(CP) -p $(BIN) $(BIN_PATH) endif @@ -193,21 +96,13 @@ cp_lib: $(LIB) | mktree $(CP) -p $(LIB) $(LIB_PATH) endif -cp_www: - $(CP) -p $(WWW) $(WWW_PATH) - -cp_conf: bsta.conf - $(CP) bsta.conf $(CONF) - -cp_cron: bsta.cron - $(SUDO) $(CP) bsta.cron $(CRON) -install: all cp_bin cp_lib cp_www cp_conf cp_cron +install: all cp_bin cp_lib clean: - $(RM) -f configure.pl $(TO_GENERATE) $(PERL_WRAP_EXEC) $(PERL_WRAP_EXEC:=.c) + $(RM) -f configure.pl $(TO_GENERATE) $(PERL) config/configure.1.pl $(DEFAULT_CONFIGFILE) < makefile.1.mak > makefile -PHONY: all clean install setuid exec mktree cp_bin cp_lib cp_www cp_conf cp_cron +PHONY: all clean install exec mktree cp_bin cp_lib diff --git a/oldlogs.1.pl b/oldlogs.1.pl index dbb4421..9a52809 100644 --- a/oldlogs.1.pl +++ b/oldlogs.1.pl @@ -33,13 +33,12 @@ use botm_common ( 'system_encoded', 'opendir_encoded', 'readdir_decoded', '_x_encoded', 'stat_encoded', - 'unlink_encoded', 'rename_encoded' + 'unlink_encoded', 'rename_encoded', 'env_pwd_decoded' ); ###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / ###PERL_GZIP: GZIP = gzip -###PERL_LOG_PATH: LOG_PATH = /botm/log/bsta/ ###PERL_LOG_SIZE_LIMIT: LOG_SIZE_LIMIT = 65536 ###PERL_LOGS_UNCOMPRESSED: LOGS_UNCOMPRESSED = 2 ###PERL_LOGS_TOTAL: LOGS_TOTAL = 10 @@ -49,7 +48,7 @@ binmode STDOUT, ':encoding(UTF-8)'; binmode STDERR, ':encoding(UTF-8)'; decode_argv(); -my $log_path = ($ARGV[0] ne '' ) ? $ARGV[0]: LOG_PATH(); +my $log_path = ($ARGV[0] ne '' ) ? $ARGV[0]: env_pwd_decoded; my $log_size_limit = ($ARGV[1] =~ /^[0-9]+$/) ? int($&) : LOG_SIZE_LIMIT(); my $logs_total = ($ARGV[2] =~ /^[0-9]+$/) ? int($&) : LOGS_TOTAL(); my $logs_uncompressed = ($ARGV[3] =~ /^[0-9]+$/) ? int($&) : LOGS_UNCOMPRESSED(); diff --git a/ong.1.pl b/ong.1.pl deleted file mode 100644 index df5eab0..0000000 --- a/ong.1.pl +++ /dev/null @@ -1,213 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# ong.pl is generated from ong.1.pl. -# -# The ONG bot -# -# Copyright (C) 2016, 2017, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'open_encoded', -); -use bsta_lib ( - 'STATE', - 'ong', - 'write_static_viewer_page', 'write_index', 'write_static_goto', - 'read_default', 'read_frame_data', 'read_settings', 'read_goto', - 'read_state', 'write_state' -); - -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my $time = time(); -srand ($time-$$); - -my %settings; -my %state; -my %new_state; -# my %goto_list; -my %default; -my %frame_data; -my %frame_1_data; -my %frame_2_data; -my %frame_3_data; - -my $fh; -my $ongstate; -my $frame; -my $next_ong; -my $ongtime; -my $static_timer; -my $timer; -my $last; -my $r = 0; - -$ongtime = int($time / 3600) * 3600; # check time as if it was last full hour! - -print $time.' - '.$ongtime."\n"; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -unless (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STATE_PATH())) { - print "NO STATEFILE\n\n"; - exit; -} -unless (flock($fh, 2)) { - print "NO STATELOCK\n\n"; - close ($fh); - exit; -} -%state = read_state($fh); -$ongstate = int($state{'state'}); -print 'state: '.$ongstate."\n"; -unless ($ongstate > STATE->{'inactive'}) { - print "INACTIVE\n\n"; - close ($fh); - exit; -} -$next_ong = int($state{'nextong'}); -print 'ongtime: '.$next_ong."\n"; - -unless ($ongtime >= $next_ong) { - print "WAIT\n\n"; - close ($fh); - exit; -} - -%settings = read_settings(); -$static_timer = int($settings{'ongtime'}); -$timer = int($settings{'dynamicongtime'}); -$last = int($settings{'last'}); -$frame = int($state {'last'})+1; - -if (($timer > 0) && ($frame < $last)) { - $timer = int($timer / ($last - $frame)); -} -else { - $timer=0; -} - -if ($static_timer > $timer) { - $timer = $static_timer; -} -$next_ong = $ongtime + ($timer*3600); -$state{'nextong'} = $next_ong; -print 'next ongtime: '.$next_ong.' (+'.$timer.")\n"; -$state{'ongtime'}=$timer; - -if ($ongstate == STATE->{'ready'}) { - print 'next frame: '.$frame."\n"; - - %default = read_default(); - %frame_data = read_frame_data($frame); - # %goto_list = read_goto()); - - %new_state = %state; - $new_state{'last'} = $frame; - $new_state{'state'} = 1; - $new_state{'ip1'} = ''; - $new_state{'ip2'} = ''; - $new_state{'ip3'} = ''; - $new_state{'ongtime'}= $timer; - - if ($frame >= 1) { - %frame_1_data = read_frame_data($frame-1); - } - if ($frame >= 2) { - %frame_2_data = read_frame_data($frame-2); - } - if ($frame >= 3) { - %frame_3_data = read_frame_data($frame-3); - } - - $r = ong ( - $frame, # frame ID - $time, # ONG time - $timer, # timer to next ONG - 0, # update - 1, # print - \%settings, - \%default, - \%frame_data, - '' # \%goto_list - ); - if ($r && ($frame >= 2)) { - print 'static page '.($frame-1); - $r = write_static_viewer_page( - $frame-1, # frame ID - \%new_state, - \%settings, - \%default, - \%frame_1_data, # frame data - \%frame_2_data, # prev frame data - \%frame_data, # next frame data - '' # words data - ); - print (($r) ? " OK\n" : " FAIL\n"); - } - if ($r && ($frame >= 3)) { - print 'static page '.($frame-2); - $r = write_static_viewer_page( - $frame-2, # frame ID - \%new_state, - \%settings, - \%default, - \%frame_2_data, # frame data - \%frame_3_data, # prev frame data - \%frame_1_data, # next frame data - '' # words data - ); - print (($r) ? " OK\n" : " FAIL\n"); - } - if ($r && ($frame <= 2)) { - print 'index'; - $r = write_index( - \%new_state, - \%settings - ); - print (($r) ? " OK\n" : " FAIL\n"); - } - if ($r) { - print 'static GOTO'; - $r = write_static_goto( - \%new_state, - \%settings, - '' # \%goto_list - ); - print (($r) ? " OK\n" : " FAIL\n"); - } - if ($r) { - %state = %new_state; - print "ONG\n\n"; - } - else { - print "NO ONG\n\n"; - } -} -write_state($fh, \%state); -close ($fh); diff --git a/opomba.1.pl b/opomba.1.pl deleted file mode 100644 index 639097a..0000000 --- a/opomba.1.pl +++ /dev/null @@ -1,591 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/w -# opomba is generated from opomba.1.pl. -# -# The comment posting interface -# -# Copyright (C) 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'read_header_env', 'url_query_decode', - 'write_data_file', - 'html_entity_encode_dec', - 'open_encoded', - 'join_path', - 'merge_url', - 'make_id', - 'http_header_status' -); -use bsta_lib ( - 'TEXT_MODE', 'STATE', - 'get_password', - 'fail_method', 'fail_content_type', - 'redirect', - 'print_html_start', 'print_html_end', - 'print_html_head_start', 'print_html_head_end', - 'print_html_body_start', 'print_html_body_end', - 'bb_to_html', 'eval_bb', - 'merge_settings', - 'write_index', 'write_static_viewer_page', - 'read_settings', 'read_state', - 'read_words', 'write_words', - 'read_words_list', 'write_words_list' - -); - -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_CGI_VIEWER_PATH: CGI_VIEWER_PATH = /bsta/v -###PERL_CGI_WORDS_PATH: CGI_WORDS_PATH = /bsta/w - -###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 - -###PERL_COMMENT_PAGE_LENGTH:COMMENT_PAGE_LENGTH= 16 - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my $time = time(); -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 $index; -my $page; -my $ong_state; -my $last_frame; -my $fh; -my $r; - - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else { - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else { - exit fail_content_type($method, $http{'content-type'}); - } -} - -if ($ENV{'PATH_INFO'} =~ /^\/([0-9]+)$/) { - $frame = int($1); -} -elsif ($ENV{'PATH_INFO'} =~ /^\/(.+)$/) { - $ID = $1; -} -if ($cgi{'f'} =~ /^.+$/) { - $frame = int($&); -} -if ($cgi{'i'} =~ /^.+$/) { - $ID = $&; -} -$password = get_password(\%cgi); - -%settings = read_settings(); -%state = read_state(); -$ong_state = int($state{'state'}); -$last_frame = int($state{'last'}); - -$password_ok = ($password eq $settings{'password'}); - -if ($cgi{'post'} ne '') { - $post = 1; -} -elsif ($cgi{'edit'} ne '') { - $edit = 1; - if ($ID eq '') { - $ID = $cgi{'edit'}; - } -} -elsif ($cgi{'remove'} ne '') { - $remove = 1; - if ($ID eq '') { - $ID = $cgi{'remove'}; - } -} -else { - $edit = 1; - if ($cgi{'quote'} ne '') { - $quote = $cgi{'quote'}; - } -} - -if ($ID ne '') { - %post_data = read_words($ID); - if ($post_data{'frame'} ne '') { - $frame = int($post_data{'frame'}); - } -} - -unless ($frame ne '') { - exit output(0, HTTP_STATUS->{'bad_request'}, 'Frame ID not specified.'); -} -$access = ( - $password_ok || ( - ($ong_state >= STATE->{'waiting'}) && - ($frame <= $last_frame) - ) -); -unless ($access) { - exit output(0, HTTP_STATUS->{'forbidden'}, 'Not allowed to post this here now'); -} - -$words_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $frame); - -unless (open_encoded($fh, "+<:encoding(UTF-8)", $words_data_path)) { - unless (open_encoded($fh, "+>:encoding(UTF-8)", $words_data_path)) { - exit output(0, '500 Internal Server Error', 'Failed opening data file.', 1); - } -} -unless (flock($fh, 2)) { - exit output(0, HTTP_STATUS->{'internal_server_error'}, 'Failed locking data file.', 1); -} - -%words_data = read_words_list( - $fh, # file - 0, # header only -); - -@post_list = @{$words_data{'content'}}; - -for (my $i=0; $i< scalar(@post_list); $i +=1) { - if ($post_list[$i] eq $ID) { - $index = $i; - $page = int($index / COMMENT_PAGE_LENGTH()); - last; - } -} - -if ($remove || ($ID ne '')) { - unless ($index ne '') { - close($fh); - exit output(0, HTTP_STATUS->{'not_found'}, $remove ? 'Nothing to remove.' : 'No such message.'); - } - unless ($cgi{'key'} eq $post_data{'key'}) { - close($fh); - exit output(0, HTTP_STATUS->{'bad_request'}, 'Invalid request.'); - } -} -if ($remove) { - unless (($method eq 'POST') && ($cgi{'i'} ne '')) { # followed a link, not confirmed yet - close($fh); - exit output(0, '', '', 1); - } -} -else { - unless (($method eq 'POST') && $post) { # followed a link, not confirmed yet - close($fh); - exit output(0, '', '', 1); - } -} -if (!$remove) { - unless ($cgi{'words'} ne '') { - exit output(0, HTTP_STATUS->{'bad_request'}, 'Where are your words?', 1); - } -} -unless ($cgi{'username'} ne '') { - close($fh); - exit output(0, HTTP_STATUS->{'bad_request'}, 'Missing user name.', 1); -} -if ($remove || ($ID ne '')) { - unless ($cgi{'username'} eq $post_data{'name'}) { - close($fh); - exit output(0, HTTP_STATUS->{'forbidden'}, 'Wrong user name.', 1); - } -} -if ($remove || ($ID ne '')) { - unless ($cgi{'password'} ne '') { - close($fh); - exit output(0, HTTP_STATUS->{'bad_request'}, 'Missing password.', 1); - } - unless ( - ($cgi{'password'} eq $post_data{'password'}) || ( - ($cgi{'password'} eq $settings{'password'}) && - $password_ok - ) - ) { - close($fh); - exit output(0, HTTP_STATUS->{'forbidden'}, 'Wrong password.', 1); - } - if ($password_ok) { - $cgi{'password'} = $post_data{'password'}; - } -} -unless ($cgi{'password2'} eq '') { - close($fh); - # 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 - -if ($remove) { - splice @post_list, $index, 1; - $words_data{'posts'} = scalar(@post_list); - $words_data{'content'} = \@post_list; - - $r = write_words_list($fh, \%words_data); - unless ($r) { - close($fh); - exit output(0, HTTP_STATUS->{'internal_server_error'}, 'Failed writing data file.'); - } - - close ($fh); - - if (open_encoded($fh, ">>:encoding(UTF-8)", LOG_WORDS_PATH())) { - delete ($post_data{'password'}); - print $fh "$time REMOVE $ID\n"; - write_data_file( - $fh, \%post_data, '', - 0, 0, 0, - '>>', 1 - ); - print $fh "\n\n"; - close ($fh); - } - - $ID = 'insw'; - exit output(1); -} - -if ($ID eq '') { - $ID = make_id($frame, 1); -} -if ($index eq '') { - $index = scalar(@post_list); - $page = int($index / COMMENT_PAGE_LENGTH()); - if ($index > 0) { - $last_ID = $post_list[-1]; - %last_post_data = read_words($last_ID); - 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); -$words_data{'content'} = \@post_list; - -$post_data{'frame'} = $frame; -$post_data{'name'} = $cgi{'username'}; -$post_data{'password'} = $cgi{'password'}; -if ($post_data{'posttime'} eq '') { - $post_data{'posttime'} = $time; -} -else { - $post_data{'edittime'} = $time; -} -if ($post_data{'key'} eq '') { - my $new_key = ''; - for (my $i=1; $i<16; $i+=1) { - $new_key .= sprintf('%02X', int(rand(0x100))); - } - $post_data{'key'} = $new_key; -} -$post_data{'content'} = $cgi{'words'}; - -$r = write_words($ID, \%post_data); -unless ($r) { - close($fh); - exit output(0, HTTP_STATUS->{'internal_server_error'}, 'Failed writing post file.', 1, 0); -} - -$r = write_words_list($fh, \%words_data); -unless ($r) { - close($fh); - exit output(0, HTTP_STATUS->{'internal_server_error'}, 'Failed writing data file.', 1, 0); -} - -close($fh); - -if (($frame == 0) && ($ong_state > STATE->{'inactive'})) { - write_index(\%state, \%settings); -} -elsif ($frame >= 1) { - write_static_viewer_page( - $frame, - \%state, - \%settings, - '', # default - '', # frame data - '', # prev frame data - '', # next frame data - \%words_data - ); -} - -if (open_encoded($fh, ">>:encoding(UTF-8)", LOG_WORDS_PATH())) { - delete ($post_data{'password'}); - print $fh "$time POST $ID\n"; - write_data_file( - $fh, \%post_data, '', - 0, 0, 0, - '>>', 1 - ); - print $fh "\n\n"; - close ($fh); -} - -exit output(1); - - -sub output { - (my $done, my $status, my $message, my $show_content) = @_; - - my $return_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - { - 'path' => $frame, - 'query' => { - 'b' => TEXT_MODE->{'words'}, - 'i' => $page, - 'p' => ($password_ok ? $settings{'password'} : '') - }, - 'fragment' => $ID - } - ); - if ($done) { - return redirect($method, $return_url, HTTP_STATUS->{'see_other'}); - } - - if ($status ne '') { - print http_header_status($status); - } - print "Content-type: text/html; charset=UTF-8\n\n"; - if ($method eq 'HEAD') { - return; - } - - my $title; - my $name; - my $content; - - if ($remove) { - $title = 'Remove message "'.$ID.'"'; - } - elsif ($ID ne '') { - $title = 'Edit message "'.$ID.'"'; - } - else { - $title = 'Words'; - } - if ($frame ne '') { - $title = $frame.'. '.$title; - } - - if ($cgi{'username'} ne '') { - $name = $cgi{'username'} - } - elsif ($post_data{'name'} ne '') { - $name = $post_data{'name'} - } - else { - $name = ''; - } - - if ($cgi{'words'} ne '') { - $content = $cgi{'words'}; - } - elsif ($quote ne '') { - my %quote_data = read_words($quote); - $content = '[quote="'.$quote_data{'name'}.'"]'.$quote_data{'content'}.'[/quote]'; - } - elsif (($cgi{'edit'} ne '') || $remove) { - $content = $post_data{'content'}; - } - else { - $content = ''; - } - - my $_password = $password_ok ? html_entity_encode_dec($settings{'password'}, 1) : ''; - my $_key = html_entity_encode_dec($post_data{'key'}, 1); - my $_ID = html_entity_encode_dec($ID, 1); - my $_title = html_entity_encode_dec($title, 1); - my $_message = html_entity_encode_dec($message, 1); - my $_story = html_entity_encode_dec($settings{'story'}, 1); - my $_name = html_entity_encode_dec($name, 1); - my $_content = html_entity_encode_dec($content, 1); - my $_empty = html_entity_encode_dec($cgi{'password2'}, 1); - my $_website_name = html_entity_encode_dec(WEBSITE_NAME(), 1); - my $_post_url = html_entity_encode_dec(CGI_WORDS_PATH(), 1); - my $_return_url = html_entity_encode_dec($return_url, 1); - - print_html_start(\*STDOUT); - print_html_head_start(\*STDOUT); - - print ' '.$_title.' • '.$_story.' • '.$_website_name.''; - - print_html_head_end(\*STDOUT); - print_html_body_start(\*STDOUT); - - print '
    '."\n"; - - print '
    '."\n"; - print '

    '.$_title.'

    '."\n"; - print '
    '."\n"; - - print '
    '."\n"; - - if ($message ne '') { - print '
    '."\n"; - - print '
    '."\n"; - print ' '.$_message.''."\n"; - print '
    '."\n"; - - print '
    '."\n"; - } - - print '
    '."\n"; - - if ($show_content) { - print '
    '."\n"; - print '
    '."\n"; - unless ($remove) { - print ' Your words:'."\n"; - print ' '."\n"; - } - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - print ' '."\n"; - if ($remove) { - print ' '."\n"; - } - else { - print ' '."\n"; - } - print '
    Your name:
    '.(($ID ne '') ? 'Password' : 'Optional password').': '.(($ID ne '') ? '' : '(if you want to edit later)').'
    Leave this empty: '."\n"; - print ' '."\n"; - print ' '."\n"; - print '
    '."\n"; - print ' '."\n"; - if ($ID ne '') { - print ' '."\n"; - } - print ' '."\n"; - if ($password_ok) { - print ' '."\n"; - } - print '
    '."\n"; - if ($content ne ''){ - print '
    '."\n"; - print '
    '."\n"; - print '
    '."\n"; - print ' Preview:'."\n"; - print '
    '."\n"; - print '
    '."\n"; - print bb_to_html( - eval_bb( - $content, - 0, - $password_ok ? $settings{'password'} : '' - ) - )."\n"; - print '
    '."\n"; - print '
    '."\n"; - } - print '
    '."\n"; - } - print ' '."\n"; - - print '
    '."\n"; - - print_html_body_end(\*STDOUT, $ong_state == STATE->{'inactive'}); - print_html_end(\*STDOUT); -} diff --git a/reset.1.pl b/reset.1.pl deleted file mode 100644 index 9aa9541..0000000 --- a/reset.1.pl +++ /dev/null @@ -1,160 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# reset is generated from reset.1.pl. -# -# Reset BSTA state -# -# Copyright (C) 2016, 2017, 2018, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'write_data_file', - 'opendir_encoded', 'readdir_decoded', 'unlink_encoded', - 'join_path' -); -use bsta_lib ( - 'STATE', 'INTF_STATE', 'CHAT_STATE', - 'write_index', - 'merge_settings', - 'get_page_file', 'get_frame_file', - 'read_settings', 'read_default', 'read_frame_data', 'read_attachment', 'read_state' -); - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -decode_argv(); - -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_DATA_CHAT_PATH: DATA_CHAT_PATH = /botm/data/bsta/chat -###PERL_DATA_DEFAULT_PATH: DATA_DEFAULT_PATH = /botm/data/bsta/default -###PERL_DATA_LIST_PATH: DATA_LIST_PATH = /botm/data/bsta/list -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state -###PERL_DATA_STORY_PATH: DATA_STORY_PATH = /botm/data/bsta/story -###PERL_DATA_WORDS_PATH: DATA_WORDS_PATH = /botm/data/bsta/words/ - -###PERL_WWW_PATH: WWW_PATH = /botm/www/ - -###PERL_RESET_PASSWORD: RESET_PASSWORD = '' - -my %story; -my %state; -my %chat; -my %settings; -my %goto_list; -my %default; -my $last_frame; -my @remove_list; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -%settings = read_settings(); -%state = read_state(); -unless ( - ($ARGV[0] ne '') && ( - ($ARGV[0] eq $settings{'password'}) || - ($ARGV[0] eq RESET_PASSWORD()) - ) -) { - print STDERR "Wrong password; no reset.\n"; - exit 1; -} - -$last_frame = (int($settings{'last'}) > int($state{'last'})) ? - int($settings{'last'}) : int($state{'last'}); -%default = read_default(); - -for (my $frame=0; $frame<=$last_frame; $frame+=1) { - my %frame_data = read_frame_data($frame, \%default); - unless ($frame == 0) { - push @remove_list, get_page_file($frame, \%frame_data, \%settings); - } - push @remove_list, get_frame_file($frame, \%frame_data, \%settings); -} -push @remove_list, 'goto.htm'; -for (my $i=0; ;$i+=1) { - my %file_data; - - %file_data = read_attachment($i); - if ($file_data{'frame'} eq '') { - last; - } - if ($file_data{'content'} ne '') { - next; - } - push @remove_list, $file_data{'filename'}; -} - -%state = ( - 'state' => STATE->{'inactive'}, - 'last' => 0, - 'ongtime' => '', - 'nextong' => '', - 'ip1' => '', - 'ip2' => '', - 'ip3' => '' -); -%story = ( - 'id' => 0, - 'letter' => '', - 'lastip' => '0.0.0.0', - 'content' => '', - 'pass' => 0, - 'state' => INTF_STATE->{'X'} -); -%chat = ( - 'id' => 0, - 'state' => CHAT_STATE->{'disconnected'}, - 'content' => '' -); -%goto_list = ( -); - -write_data_file(DATA_STATE_PATH(), \%state); -write_data_file(DATA_STORY_PATH(), \%story); -write_data_file(DATA_CHAT_PATH() , \%chat); -write_data_file(DATA_LIST_PATH() , \%goto_list); - -write_index( - \%state, - \%settings, - $story{'pass'}, - $story{'state'}, - 0 # pause -); - -if (opendir_encoded(my $dir, DATA_WORDS_PATH())) { - while (defined (my $file_name = readdir_decoded($dir))) { - if ($file_name !~ /^[0-9]+$/) { - next; - } - my $full_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $file_name); - # print "RM $full_path\n"; - unlink_encoded ($full_path); - } -} -foreach my $file_name (@remove_list) { - my $full_path = join_path(PATH_SEPARATOR(), WWW_PATH(), $file_name); - # print "RM $full_path\n"; - unlink_encoded ($full_path); -} diff --git a/settings-again.txt b/settings-again.txt deleted file mode 100644 index 8f13d1c..0000000 --- a/settings-again.txt +++ /dev/null @@ -1,92 +0,0 @@ -# In this file are defined values specific for the user's system - - -# target name. settings file (THIS FILE) is "settings-TARGET_NAME.txt" -# where TARGET_NAME is the value -target: again - -name: bstagain - - -# Where the software will be located -bin_path: /botm/bin/bstagain - -# where the libraries will be located -lib_path: /botm/lib/bstagain - -# where the software will remember data -data_path: /botm/data/bstagain - -#where the software will record logs -log_path: /botm/log/bstagain - -#for temporary fies -tmp_path: /botm/tmp/bstagain - -#for the www server -www_path : /botm/www/1190/bstagain -cgi_path : /bstagain -conf_path: /botm/etc/www/conf/1190 - -#cron files directory -cron_path: /etc/cron.d - -path: /usr/local/bin:/usr/bin:/bin -# The path environment variable. Must be overwritten if SETUID. -# Otherwise launching programs may fail. -# (Perl security...) - - -#paths to software - -chmod: /usr/bin/chmod -cp : /usr/bin/cp -gzip : /usr/bin/gzip -mkdir: /usr/bin/mkdir -mv : /usr/bin/mv -perl : /usr/bin/perl -rm : /usr/bin/rm -sudo : /usr/bin/sudo - -CC: /usr/bin/gcc -CF: -g -Wall - - -# How big can a log file be -log_size_limit: 65536 - -# How many uncompressed old logs to keep -logs_uncompressed: 2 - -# How many old logs to keep -logs_total: 10 - -# When to deal with old logs -oldlogs_schedule: 1 4 * * * - -# When to run the ONG bot -ong_schedule: 0 * * * * - -# When to RESET EVERYTHING -reset_schedule: 33 4 * * * -reset_password: again - -cron_user: b - - -scheme : http -website : 1190.bicyclesonthemoon.info -website_name: Bicycles on the Moon -favicon_path: /img/favicon.png -intf_date : 28-Sep-2016 20:34 -coin_date : 13-Nov-2016 22:15 - -story_length : 16 -firstpage_length: 4 -page_length : 16 - -comment_page_length: 40 - -story_credits: "BSTA" by Balthasar Szczepański -intf_credits: Online interface v$_version © Balthasar Szczepański; AGPL 3 license -source_url: http://bicyclesonthemoon.info/git-projects/?p=ott/bsta diff --git a/settings-bsta.txt b/settings-bsta.txt deleted file mode 100644 index a02554d..0000000 --- a/settings-bsta.txt +++ /dev/null @@ -1,92 +0,0 @@ -# In this file are defined values specific for the user's system - - -# target name. settings file (THIS FILE) is "settings-TARGET_NAME.txt" -# where TARGET_NAME is the value -target: bsta - -name: bsta - - -# Where the software will be located -bin_path: /botm/bin/bsta - -# where the libraries will be located -lib_path: /botm/lib/bsta - -# where the software will remember data -data_path: /botm/data/bsta - -#where the software will record logs -log_path: /botm/log/bsta - -#for temporary fies -tmp_path: /botm/tmp/bsta - -#for the www server -www_path : /botm/www/1190/bsta -cgi_path : /bsta -conf_path: /botm/etc/www/conf/1190 - -#cron files directory -cron_path: /etc/cron.d - -path: /usr/local/bin:/usr/bin:/bin -# The path environment variable. Must be overwritten if SETUID. -# Otherwise launching programs may fail. -# (Perl security...) - - -#paths to software - -chmod: /usr/bin/chmod -cp : /usr/bin/cp -gzip : /usr/bin/gzip -mkdir: /usr/bin/mkdir -mv : /usr/bin/mv -perl : /usr/bin/perl -rm : /usr/bin/rm -sudo : /usr/bin/sudo - -CC: /usr/bin/gcc -CF: -g -Wall - - -# How big can a log file be -log_size_limit: 65536 - -# How many uncompressed old logs to keep -logs_uncompressed: 2 - -# How many old logs to keep -logs_total: 10 - -# When to deal with old logs -oldlogs_schedule: 0 4 * * * - -# When to run the ONG bot -ong_schedule: 0 * * * * - -# When to RESET EVERYTHING -reset_schedule: #33 4 * * * -reset_password: - -cron_user: b - - -scheme : http -website : 1190.bicyclesonthemoon.info -website_name: Bicycles on the Moon -favicon_path: /img/favicon.png -intf_date : 28-Sep-2016 20:34 -coin_date : 13-Nov-2016 22:15 - -story_length : 16 -firstpage_length: 4 -page_length : 16 - -comment_page_length: 40 - -story_credits: "BSTA" by Balthasar Szczepański -intf_credits: Online interface v$_version © Balthasar Szczepański; AGPL 3 license -source_url: http://bicyclesonthemoon.info/git-projects/?p=ott/bsta diff --git a/settings-debug.txt b/settings-debug.txt index 40e8d9b..88eac5d 100644 --- a/settings-debug.txt +++ b/settings-debug.txt @@ -5,37 +5,14 @@ # where TARGET_NAME is the value target: debug -name: test-bsta +name: test-oldlogs # Where the software will be located -bin_path: /botm/bin/test-bsta +bin_path: /botm/bin/test-oldlogs # where the libraries will be located -lib_path: /botm/lib/test-bsta - -# where the software will remember data -data_path: /botm/data/test-bsta - -#where the software will record logs -log_path: /botm/log/test-bsta - -#for temporary fies -tmp_path: /botm/tmp/test-bsta - -#for the www server -www_path : /botm/www/1190/bstatest -cgi_path : /bstatest -conf_path: /botm/etc/www/conf/1190 - -#cron files directory -cron_path: /etc/cron.d - -path: /usr/local/bin:/usr/bin:/bin -# The path environment variable. Must be overwritten if SETUID. -# Otherwise launching programs may fail. -# (Perl security...) - +lib_path: /botm/lib/test-oldlogs #paths to software @@ -46,10 +23,6 @@ mkdir: /usr/bin/mkdir mv : /usr/bin/mv perl : /usr/bin/perl rm : /usr/bin/rm -sudo : /usr/bin/sudo - -CC: /usr/bin/gcc -CF: -g -Wall # How big can a log file be @@ -61,32 +34,3 @@ logs_uncompressed: 2 # How many old logs to keep logs_total: 10 -# When to deal with old logs -oldlogs_schedule: #0 4 * * * - -# When to run the ONG bot -ong_schedule: #0 * * * * - -# When to RESET EVERYTHING -reset_schedule: #33 4 * * * -reset_password: bstreset - -cron_user: b - - -scheme : http -website : 1190.bicyclesonthemoon.info -website_name: Bicycles on the Moon -favicon_path: /img/favicon.png -intf_date : 28-Sep-2016 20:34 -coin_date : 13-Nov-2016 22:15 - -story_length : 16 -firstpage_length: 4 -page_length : 16 - -comment_page_length: 4 - -story_credits: "BSTA" by Balthasar Szczepański -intf_credits: Online interface v$_version © Balthasar Szczepański; AGPL 3 license -source_url: http://bicyclesonthemoon.info/git-projects/?p=ott/bsta diff --git a/settings-release.txt b/settings-release.txt new file mode 100644 index 0000000..05e72ea --- /dev/null +++ b/settings-release.txt @@ -0,0 +1,36 @@ +# In this file are defined values specific for the user's system + + +# target name. settings file (THIS FILE) is "settings-TARGET_NAME.txt" +# where TARGET_NAME is the value +target: release + +name: oldlogs + + +# Where the software will be located +bin_path: /botm/bin/oldlogs + +# where the libraries will be located +lib_path: /botm/lib/oldlogs + +#paths to software + +chmod: /usr/bin/chmod +cp : /usr/bin/cp +gzip : /usr/bin/gzip +mkdir: /usr/bin/mkdir +mv : /usr/bin/mv +perl : /usr/bin/perl +rm : /usr/bin/rm + + +# How big can a log file be +log_size_limit: 65536 + +# How many uncompressed old logs to keep +logs_uncompressed: 2 + +# How many old logs to keep +logs_total: 10 + diff --git a/settings.txt b/settings.txt index 7d809c5..2760223 100644 --- a/settings.txt +++ b/settings.txt @@ -15,7 +15,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -_version: 1.2.6 +_version: 1.0.0y _SHEBANG: #!$0 @@ -27,101 +27,6 @@ _PERL_OUR: our $0 = $1; _PERL_OUR_STR: @_PERL_OUR(\$$0,@_PERL_STR($1)) -_bin_path = @_PATH( $bin_path, ) -_bin_2words_path = @_PATH( $bin_path, 2words ) -_bin_attach_path = @_PATH( $bin_path, attach ) -_bin_bbcode_path = @_PATH( $bin_path, bbcode ) -_bin_coin_path = @_PATH( $bin_path, chat ) -_bin_frame_path = @_PATH( $bin_path, frame ) -_bin_goto_path = @_PATH( $bin_path, goto ) -_bin_info_path = @_PATH( $bin_path, info ) -_bin_oldlogs_path = @_PATH( $bin_path, oldlogs.pl) -_bin_ong_path = @_PATH( $bin_path, ong.pl ) -_bin_reset_path = @_PATH( $bin_path, reset.pl ) -_bin_viewer_path = @_PATH( $bin_path, viewer ) -_bin_words_path = @_PATH( $bin_path, opomba ) - -_cgi_path = @_PATH( $cgi_path, ) -_cgi_2words_path = @_PATH( $cgi_path, 2words ) -_cgi_attach_path = @_PATH( $cgi_path, a ) -_cgi_bbcode_path = @_PATH( $cgi_path, b ) -_cgi_coin_path = @_PATH( $cgi_path, coin ) -_cgi_css_path = @_PATH( $cgi_path, bsta.css ) -_cgi_frame_path = @_PATH( $cgi_path, f ) -_cgi_goto_path = @_PATH( $cgi_path, g ) -_cgi_info_path = @_PATH( $cgi_path, i ) -_cgi_list_path = @_PATH( $cgi_path, goto.htm ) -_cgi_logo_path = @_PATH( $cgi_path, botmlogo.png) -_cgi_timer_path = @_PATH( $cgi_path, timer.js ) -_cgi_viewer_path = @_PATH( $cgi_path, v ) -_cgi_words_path = @_PATH( $cgi_path, w ) - -_data_path = @_PATH( $data_path, ) -_data_attach_path = @_PATH( $data_path, a ) -_data_chat_path = @_PATH( $data_path, chat ) -_data_coin_path = @_PATH( $data_path, coincidence) -_data_default_path = @_PATH( $data_path, default ) -_data_list_path = @_PATH( $data_path, list ) -_data_noaccess_path = @_PATH( $data_path, noaccess ) -_data_settings_path = @_PATH( $data_path, settings ) -_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_spam_path = @_PATH( $log_path, words_spam.log) -_log_words_path = @_PATH( $log_path, words.log ) - -_www_path = @_PATH( $www_path, ) -_www_goto_path = @_PATH( $www_path, goto.htm ) -_www_index_path = @_PATH( $www_path, index.htm) - -_conf_path = @_PATH($conf_path, $name\.conf) -_cron_path = @_PATH($cron_path, $name) - - -CONF_BIN = $_bin_path -CONF_BIN_2WORDS = $_bin_2words_path -CONF_BIN_ATTACH = $_bin_attach_path -CONF_BIN_BBCODE = $_bin_bbcode_path -CONF_BIN_COIN = $_bin_coin_path -CONF_BIN_FRAME = $_bin_frame_path -CONF_BIN_GOTO = $_bin_goto_path -CONF_BIN_INFO = $_bin_info_path -CONF_BIN_VIEWER = $_bin_viewer_path -CONF_BIN_WORDS = $_bin_words_path - -CONF_CGI_2WORDS = $_cgi_2words_path -CONF_CGI_ATTACH = $_cgi_attach_path -CONF_CGI_BBCODE = $_cgi_bbcode_path -CONF_CGI_COIN = $_cgi_coin_path -CONF_CGI_FRAME = $_cgi_frame_path -CONF_CGI_GOTO = $_cgi_goto_path -CONF_CGI_INFO = $_cgi_info_path -CONF_CGI_VIEWER = $_cgi_viewer_path -CONF_CGI_WORDS = $_cgi_words_path - - -CRON_ONG = $_bin_ong_path -CRON_OLDLOGS = $_bin_oldlogs_path -CRON_RESET = $_bin_reset_path - -CRON_USER = $cron_user - -CRON_OLDLOGS_SCHEDULE = $oldlogs_schedule -CRON_ONG_SCHEDULE = $ong_schedule -CRON_RESET_SCHEDULE = $reset_schedule -CRON_RESET_PASSWORD = $reset_password - -CRON_LOG_SIZE_LIMIT = $log_size_limit -CRON_LOGS_UNCOMPRESSED = $logs_uncompressed -CRON_LOGS_TOTAL = $logs_total - -CRON_LOG = $_log_path -CRON_ONG_LOG = $_log_ong_path - - MAKE_TARGET = TARGET = $target MAKE_CHMOD = CHMOD=$chmod @@ -129,90 +34,21 @@ MAKE_CP = CP =$cp MAKE_MKDIR = MKDIR=$mkdir MAKE_PERL = PERL =$perl MAKE_RM = RM =$rm -MAKE_SUDO = SUDO =$sudo - -MAKE_CC = CC =$CC -MAKE_CF = CF =$CF - -MAKE_CONF = CONF = $_conf_path -MAKE_CRON = CRON = $_cron_path MAKE_BIN_PATH = BIN_PATH = $bin_path -MAKE_DATA_PATH = DATA_PATH = $data_path -MAKE_DATA_WORDS_PATH = DATA_WORDS_PATH = $_data_words_path MAKE_LIB_PATH = LIB_PATH = $lib_path -MAKE_LOG_PATH = LOG_PATH = $log_path -MAKE_TMP_PATH = TMP_PATH = $tmp_path -MAKE_WWW_PATH = WWW_PATH = $www_path PERL_LIB = @_PERL_USE_2(lib, @_PERL_STR($lib_path)) -PERL_SET_PATH = \$ENV{'PATH'} = @_PERL_STR($path); - PERL_EXPORT_VERSION = @_PERL_OUR_STR( VERSION, $_version) PERL_PATH_SEPARATOR = @_PERL_CONSTANT_STR( PATH_SEPARATOR, $_PATH_SEPARATOR) -PERL_CGI_PATH = @_PERL_CONSTANT_STR( CGI_PATH , $_cgi_path ) -PERL_CGI_2WORDS_PATH = @_PERL_CONSTANT_STR( CGI_2WORDS_PATH, $_cgi_2words_path) -PERL_CGI_ATTACH_PATH = @_PERL_CONSTANT_STR( CGI_ATTACH_PATH, $_cgi_attach_path) -PERL_CGI_BBCODE_PATH = @_PERL_CONSTANT_STR( CGI_BBCODE_PATH, $_cgi_bbcode_path) -PERL_CGI_COIN_PATH = @_PERL_CONSTANT_STR( CGI_COIN_PATH , $_cgi_coin_path ) -PERL_CGI_CSS_PATH = @_PERL_CONSTANT_STR( CGI_CSS_PATH , $_cgi_css_path ) -PERL_CGI_FRAME_PATH = @_PERL_CONSTANT_STR( CGI_FRAME_PATH , $_cgi_frame_path ) -PERL_CGI_GOTO_PATH = @_PERL_CONSTANT_STR( CGI_GOTO_PATH , $_cgi_goto_path ) -PERL_CGI_INFO_PATH = @_PERL_CONSTANT_STR( CGI_INFO_PATH , $_cgi_info_path ) -PERL_CGI_LIST_PATH = @_PERL_CONSTANT_STR( CGI_LIST_PATH , $_cgi_list_path ) -PERL_CGI_LOGO_PATH = @_PERL_CONSTANT_STR( CGI_LOGO_PATH , $_cgi_logo_path ) -PERL_CGI_TIMER_PATH = @_PERL_CONSTANT_STR( CGI_TIMER_PATH , $_cgi_timer_path ) -PERL_CGI_VIEWER_PATH = @_PERL_CONSTANT_STR( CGI_VIEWER_PATH, $_cgi_viewer_path) -PERL_CGI_WORDS_PATH = @_PERL_CONSTANT_STR( CGI_WORDS_PATH , $_cgi_words_path ) - -PERL_DATA_PATH = @_PERL_CONSTANT_STR( DATA_PATH , $_data_path ) -PERL_DATA_ATTACH_PATH = @_PERL_CONSTANT_STR( DATA_ATTACH_PATH , $_data_attach_path ) -PERL_DATA_CHAT_PATH = @_PERL_CONSTANT_STR( DATA_CHAT_PATH , $_data_chat_path ) -PERL_DATA_COIN_PATH = @_PERL_CONSTANT_STR( DATA_COIN_PATH , $_data_coin_path ) -PERL_DATA_DEFAULT_PATH = @_PERL_CONSTANT_STR( DATA_DEFAULT_PATH , $_data_default_path ) -PERL_DATA_LIST_PATH = @_PERL_CONSTANT_STR( DATA_LIST_PATH , $_data_list_path ) -PERL_DATA_NOACCESS_PATH = @_PERL_CONSTANT_STR( DATA_NOACCESS_PATH, $_data_noaccess_path) -PERL_DATA_SETTINGS_PATH = @_PERL_CONSTANT_STR( DATA_SETTINGS_PATH, $_data_settings_path) -PERL_DATA_STATE_PATH = @_PERL_CONSTANT_STR( DATA_STATE_PATH , $_data_state_path ) -PERL_DATA_STORY_PATH = @_PERL_CONSTANT_STR( DATA_STORY_PATH , $_data_story_path ) -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 ) -PERL_WWW_GOTO_PATH = @_PERL_CONSTANT_STR( WWW_GOTO_PATH , $_www_goto_path ) -PERL_WWW_INDEX_PATH = @_PERL_CONSTANT_STR( WWW_INDEX_PATH, $_www_index_path) - -PERL_SCHEME = @_PERL_CONSTANT_STR( SCHEME , $scheme ) -PERL_WEBSITE = @_PERL_CONSTANT_STR( WEBSITE , $website ) -PERL_WEBSITE_NAME = @_PERL_CONSTANT_STR( WEBSITE_NAME, $website_name) -PERL_FAVICON_PATH = @_PERL_CONSTANT_STR( FAVICON_PATH, $favicon_path) - -PERL_COIN_DATE = @_PERL_CONSTANT_STR( COIN_DATE, $coin_date) -PERL_INTF_DATE = @_PERL_CONSTANT_STR( INTF_DATE, $intf_date) - -PERL_STORY_CREDITS = @_PERL_CONSTANT_STR( STORY_CREDITS, $story_credits) -PERL_INTF_CREDITS = @_PERL_CONSTANT_STR( INTF_CREDITS , @intf_credits) -PERL_SOURCE_URL = @_PERL_CONSTANT_STR( SOURCE_URL , $source_url) - PERL_GZIP = @_PERL_CONSTANT_STR( GZIP, $gzip) -PERL_RESET_PASSWORD = @_PERL_CONSTANT_STR( RESET_PASSWORD, $reset_password) - PERL_LOG_SIZE_LIMIT = @_PERL_CONSTANT( LOG_SIZE_LIMIT , $log_size_limit) PERL_LOGS_UNCOMPRESSED = @_PERL_CONSTANT( LOGS_UNCOMPRESSED, $logs_uncompressed) PERL_LOGS_TOTAL = @_PERL_CONSTANT( LOGS_TOTAL , $logs_total) -PERL_STORY_LENGTH = @_PERL_CONSTANT( STORY_LENGTH , $story_length) -PERL_PAGE_LENGTH = @_PERL_CONSTANT( PAGE_LENGTH , $page_length) -PERL_FIRSTPAGE_LENGTH = @_PERL_CONSTANT( FIRSTPAGE_LENGTH, $firstpage_length) - -PERL_COMMENT_PAGE_LENGTH= @_PERL_CONSTANT( COMMENT_PAGE_LENGTH, $comment_page_length) - RUN_PERL = @_SHEBANG($perl) diff --git a/timer.js b/timer.js deleted file mode 100644 index 964763f..0000000 --- a/timer.js +++ /dev/null @@ -1,95 +0,0 @@ -// timer.js -// -// The countdown script. -// -// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0 -// Copyright (C) 2017, 2024 Balthasar Szczepański -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// @license-end - -var enabled = false; - -window.onload = function () { - var e_h; - var e_m; - var e_s; - var h; - var m; - var s; - var countdown; - var timer; - - e_h = document.getElementById("ongh"); - e_m = document.getElementById("ongm"); - e_s = document.getElementById("ongs"); - - h = +(e_h.innerHTML); - m = +(e_m.innerHTML); - s = +(e_s.innerHTML); - - timer = document.getElementById("timer"); - timer.onclick = function () { - enabled = !enabled; - } - - if (e_h == null || e_m == null || e_s == null) { - // window.alert("NUL"); - } - else { - countdown = setInterval (function() { - if(isNaN(h) || isNaN(m) || isNaN(s)) { - // window.alert("NAN"); - clearInterval(countdown); - return; - } - - if (s > 0) { - s -= 1; - } - else { - s = 59; - if (m > 0) { - m -= 1; - } - else { - m == 59; - if (h > 0) { - h -= 1; - } - else { - m = 0; - s = 0; - } - } - } - - if (enabled) { - if (h == 0 && m == 0 && s == 0) { - e_h.innerHTML = "00"; - e_m.innerHTML = "00"; - e_s.innerHTML = "NG"; - // window.alert("ONG"); - clearInterval(countdown); - return; - } - else { - e_h.innerHTML = ((h < 10) ? "0" : "") + h; - e_m.innerHTML = ((m < 10) ? "0" : "") + m; - e_s.innerHTML = ((s < 10) ? "0" : "") + s; - } - } - }, 1000); - } -}; diff --git a/update.1.pl b/update.1.pl deleted file mode 100644 index 8cfba90..0000000 --- a/update.1.pl +++ /dev/null @@ -1,253 +0,0 @@ -#!/usr/bin/perl - -# update.pl is generated from update.1.pl. -# -# update already ONGed frames & stuff -# -# Copyright (C) 2016, 2017, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( -); -use bsta_lib ( - 'STATE', - 'ong', - 'write_index', 'write_static_viewer_page', 'write_static_goto', - 'read_frame_data', 'read_default', 'read_words_list', - 'read_settings', 'read_state' -); - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -decode_argv(); - -my $time = time(); -srand ($time-$$); - -my %settings = read_settings(); -my %default = read_default(); -my %state = read_state(); -my %all_frame_data = (); -my %all_words_data = (); - -my $update_goto = 0; - -my $ong_state = int($state{'state'}); -my $last_frame = ($ong_state > STATE->{'inactive'}) ? - int($state{'last'}) : - 0; - -my @list; - -my $fail = 0; - -print $time."\n"; - -foreach my $id (@ARGV) { - if ($id eq 'all') { - $update_goto = 1; - push @list, 'i'; - push @list, 'c'; - for (my $f=0; $f<=$last_frame; $f+=1) { - push @list, $f; - } - } - elsif ($id =~ /^[0-9]+$/) { - $update_goto = 1; - my $f = int($&); - if ($f <= $last_frame) { - push @list, $f - } - else { - print "$f > $last_frame\n"; - $fail += 1; - } - } - elsif ($id =~ /^[ic]$/) { - push @list, $&; - } - else { - print "$id ???\n"; - $fail += 1; - } -} - -# duplicated - before AND after normal pages! -if ($update_goto) { - print 'static GOTO'; - my $r = write_static_goto( - \%state, - \%settings, - '' # \%goto_list - ); - if ($r) { - print " OK\n"; - } - else { - print " FAIL\n"; - $fail += 1; - } -} - -foreach my $id (@list) { - print "ONG $id\n"; - my $r = ong( - $id, # frame ID - $time, # ONG time - '', # timer value; not relevant - 1, # update - 1, # print - \%settings, - \%default, - get_frame_data($id), - '' # %goto_list - ); - unless ($r) { - $fail += 1; - print "ONG FAIL!\n"; - } - make_static_pages($id); -} - -# duplicated - before AND after normal pages! -if ($update_goto) { - print 'static GOTO'; - my $r = write_static_goto( - \%state, - \%settings, - '' # \%goto_list - ); - if ($r) { - print " OK\n"; - } - else { - print " FAIL\n"; - $fail += 1; - } -} - -print "\n"; - - -sub get_frame_data { - (my $id) = @_; - - unless ($id =~ /^[0-9]+$/) { - return ''; - } - my $f = int($id); - - unless (($f >= 0) && ($f <= $last_frame)) { - return ''; - } - - my $r = $all_frame_data{$f}; - if (ref ($r)) { - return $r; - } - - my %frame_data = read_frame_data($f); - $all_frame_data{$f} = \%frame_data; - return \%frame_data; -} - -sub get_words_data { - (my $id) = @_; - - unless ($id =~ /^[0-9]+$/) { - return ''; - } - my $f = int($id); - - unless (($f >= 0) && ($f <= $last_frame)) { - return ''; - } - - my $r = $all_words_data{$f}; - if (ref ($r)) { - return $r; - } - - my %words_data = read_words_list($f, 1); - $all_words_data{$f} = \%words_data; - return \%words_data; -} - -sub make_static_page { - (my $id) = @_; - unless ($id =~ /^[0-9]+$/) { - return; - } - my $f = int($id); - unless ( - ($f >= 0) && ( - ($f < $last_frame) || ( - ($ong_state >= STATE->{'end'}) && - ($f <= $last_frame) - ) - ) - ) { - return; - } - my $r; - - if (($f == 0) && ($ong_state > STATE->{'inactive'})) { - print 'index'; - $r = write_index( - \%state, - \%settings, - ); - print (($r) ? " OK\n" : " FAIL\n"); - } - elsif ($f > 0) { - print 'static page '.$f; - $r = write_static_viewer_page ( - $f, - \%state, - \%settings, - \%default, - get_frame_data($f), - get_frame_data($f-1), - get_frame_data($f+1), - get_words_data($f) - ); - print (($r) ? " OK\n" : " FAIL\n"); - } -} - -sub make_static_pages { - (my $id) = @_; - unless ($id =~ /^[0-9]+$/) { - return; - } - my $f = int($id); - unless (($f >= 0) && ($f <= $last_frame)) { - return ''; - } - - make_static_page($f); - make_static_page($f-1); - make_static_page($f+1); - make_static_page($f); -} - -exit $fail; diff --git a/viewer.1.pl b/viewer.1.pl deleted file mode 100644 index c7d74d9..0000000 --- a/viewer.1.pl +++ /dev/null @@ -1,384 +0,0 @@ -###RUN_PERL: #!/usr/bin/perl - -# /bsta/v -# viewer is generated from viewer.1.pl. -# -# The viewer interface -# -# Copyright (C) 2016, 2017, 2019, 2020, 2023, 2024 Balthasar Szczepański -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -use strict; -use utf8; -# use Encode::Locale ('decode_argv'); -use Encode ('encode', 'decode'); - -###PERL_LIB: use lib /botm/lib/bsta -use botm_common ( - 'HTTP_STATUS', - 'read_header_env', - 'url_query_decode', - 'join_path', - 'open_encoded', '_x_encoded', - 'http_header_status', - 'merge_url' -); -use bsta_lib ( - 'STATE', 'TEXT_MODE', 'INTF_STATE', - 'fail_method', 'fail_content_type', 'redirect', - 'get_remote_addr', 'get_frame', 'get_password', - 'merge_settings', - 'print_viewer_page', - 'write_index', 'write_static_goto', 'write_static_viewer_page', - 'ong', - 'read_frame_data', 'read_default', 'read_noaccess', - 'read_words_list', 'read_settings', 'read_story', 'read_goto', - 'read_state', 'write_state', - 'get_page_file' -); - -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_CGI_PATH: CGI_PATH = /bsta/ -###PERL_CGI_VIEWER_PATH: CGI_VIEWER_PATH = /bsta/v - -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state - -###PERL_WWW_PATH: WWW_PATH = /botm/www/ - -binmode STDIN, ':encoding(UTF-8)'; -binmode STDOUT, ':encoding(UTF-8)'; -binmode STDERR, ':encoding(UTF-8)'; -# decode_argv(); - -my $time = time(); -srand ($time-$$); - -my %http; -my %cgi; -my %frame_data; -my %prev_frame_data; -my %next_frame_data; -my %default; -my %settings; -my %state; -my %new_state; -my %goto_list; -my %words_data; - -my $method; -my $frame; -my $prev_frame_data_path; -my $next_frame_data_path; -my $password; -my $password_ok; -my $IP; -my $access; -my $timer; -my $timer_unlocked; -my $fh; -my $show_command; -my $ongtime; -my $goto; -my $text_mode; -my $words_page; -my $words_data_path; -my $no_cgi; -my $force_redirect; - -delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; -###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; - -if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) { - $method = $1; -} -else{ - exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']); -} - -%http = read_header_env(\%ENV); -%cgi = url_query_decode($ENV{'QUERY_STRING'}); - -if ($method eq 'POST') { - if ($http{'content-type'} eq 'application/x-www-form-urlencoded') { - my %cgi_post = url_query_decode( ); - %cgi = merge_settings(\%cgi, \%cgi_post); - } - # multipart not supported - else{ - exit fail_content_type($method, $http{'content-type'}); - } -} -$no_cgi = (scalar (keys %cgi) == 0); - -$IP = get_remote_addr(); -$frame = get_frame(\%cgi); -$password = get_password(\%cgi); - -%settings = read_settings(); -%default = read_default(); - -if ($frame >= 0) { - %frame_data= read_frame_data($frame); -} - -$password_ok = ($password eq $settings{'password'}); - -# state & activation logic -if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STATE_PATH())) { - if (flock($fh, 2)) { - - %state = read_state($fh); - - if ($frame < 0) { - $frame = int($state{'last'}) + $frame +1; - if ($frame >= 0) { - $force_redirect = 1; - %frame_data = read_frame_data($frame); - } - } - - if ( - (int($state{'state'}) == STATE->{'waiting'}) && - ($frame == int($state{'last'})) && - ($method ne 'HEAD') && - (!$password_ok) - ) { - # register IP for progress - my %new_state = %state; - unless ( - ($state{'ip1'} eq $IP) || - ($state{'ip2'} eq $IP) || - ($state{'ip3'} eq $IP) - ) - { - if ($state{'ip1'} eq '') { - $new_state{'ip1'} = $IP; - } - elsif ($state{'ip2'} eq '') { - $new_state{'ip2'} = $IP; - } - elsif ($state{'ip3'} eq '') { - $new_state{'ip3'} = $IP; - $new_state{'state'} = STATE->{'ready'}; - } - else { - $new_state{'state'} = STATE->{'ready'}; - } - if ($new_state{'state'} == STATE->{'ready'}) { - write_static_goto(\%new_state, \%settings, ''); - write_static_viewer_page( - $frame-1, - \%new_state, - \%settings, - \%default, - '', # frame data - '', # prev frame data - \%frame_data, # next frame data, - '' # words data - ); - } - write_state($fh, \%new_state); - } - } - elsif ( - (int($state{'state'}) == STATE->{'inactive'}) && - ($frame == 1) && - (!$password_ok) - ) { - # ready to activate? - # NOTE: at this point frame 0 is already ONGed. - my %story; - my $ong_time = int($settings{'firstongtime'}); - my $r; - - %story = read_story(); - %goto_list = read_goto(); - - if ( - (int($story{'state'}) == INTF_STATE->{'>|'} ) && - (int($story{'pass'}) == 1) - ) { - # conditions met; ACTIVATE! - - # set initial state - $state{'state'} = STATE->{'waiting'}; - $state{'last'} = 1; - $state{'ip1'} = '0.0.0.0'; - $state{'ip2'} = '0.0.0.0'; - $state{'ip3'} = ''; - $state{'nextong'} = (int($time / 3600) + int($settings{'firstongtime'})) * 3600 ; - $state{'ongtime'} = $ong_time; - - # prepare to ONG frame 1 - - $r = ong( - 1, # frame ID - $time, # ONG time, - $ong_time, # timer - 0, # update - 0, # print - \%settings, - \%default, - \%frame_data, - \%goto_list - ); - if ($r) { - $r = write_index(\%state, \%settings); - } - if ($r) { - $r = write_static_goto(\%state, \%settings, \%goto_list); - } - if ($r) { - $r = write_state($fh, \%state); - } - unless ($r) { - # FAILED ONG! Story as if it was inactive! - $state{'state'} = STATE->{'inactive'}; - } - } - } - } - else { - # FAILED GET STATE! Story as if it was inactive! - $state{'state'} = STATE->{'inactive'}; - } - close ($fh); -} -else { - $state{'state'} = STATE->{'inactive'}; -} - -$access = ( - $password_ok || ( - (int($state{'state'}) >= STATE->{'waiting'}) && - ($frame <= int($state{'last'})) && - ($frame >= 0) - ) -); - -if ($access) { - if ($no_cgi) { - # no CGI - static page is OK - if ($frame == 0) { - exit redirect($method, CGI_PATH(), HTTP_STATUS->{'see_other'}); - } - elsif ($frame < int($state{'last'})) { - my $page_file = get_page_file($frame, \%frame_data, \%settings); - if (_x_encoded('-f', - join_path(PATH_SEPARATOR(), WWW_PATH() , $page_file) - )) { - my $static_url = merge_url( - {'path' => CGI_PATH()}, - {'path' => $page_file} - ); - exit redirect($method, $static_url, HTTP_STATUS->{'see_other'}); - } - } - } - if ($force_redirect) { - my $redirect_url = merge_url( - {'path' => CGI_VIEWER_PATH()}, - {'path' => $frame} - ); - unless ($no_cgi) { - delete $cgi{'f'}; # to avoid infinite loop - $redirect_url = merge_url( - {'path' => $redirect_url}, - {'query' => \%cgi} - ); - } - exit redirect($method, $redirect_url, HTTP_STATUS->{'see_other'}); - } - - if ($frame > 0) { - %prev_frame_data = read_frame_data($frame-1, \%default); - } - else { - %prev_frame_data = %default; - } - %next_frame_data = read_frame_data($frame+1, \%default); - %frame_data = merge_settings(\%default, \%frame_data); -} -else { - # replace frame data with fail state replacement - %frame_data = read_noaccess(\%default); -} - -$timer = int($state{'nextong'}) - $time; -$ongtime = int($state{'ongtime'}); -if($ongtime == 0) { - $ongtime = int($settings{'ongtime'}) -} - -$show_command = ($timer < ($ongtime*3600/3)); -if ($state{'state'} >= STATE->{'ready'}) { - $timer_unlocked = 3; -} -elsif ($state{'ip3'} ne '') { - $timer_unlocked = 3; -} -elsif ($state{'ip2'} ne '') { - $timer_unlocked = 2; -} -elsif ($state{'ip1'} ne '') { - $timer_unlocked = 1; -} -else { - $timer_unlocked = 0; -} - -$text_mode = int($cgi{'b'}); -if($text_mode > TEXT_MODE->{'words'}) { - $text_mode = TEXT_MODE->{'normal'}; -} -$words_page = int($cgi{'i'}); -$goto = int($cgi{'g'}); - -%words_data = read_words_list( - $frame, - ($text_mode != TEXT_MODE->{'words'}) -); - -if (!$access) { - print http_header_status(HTTP_STATUS->{'forbidden'}); -} -print "Content-type: text/html; charset=UTF-8\n\n"; -if($method eq 'HEAD') { - exit; -} - -print_viewer_page ( - \*STDOUT, - { - 'launch' => 0, - 'frame' => $frame, - 'access' => $access, - 'password_ok' => $password_ok, - 'timer_unlocked'=> $timer_unlocked, - 'timer' => $timer, - 'static' => 0, - 'show_command' => $show_command, - 'text_mode' => $text_mode, - 'words_page' => $words_page, - 'goto' => $goto - }, - \%state, - \%settings, - \%frame_data, - $access ? \%prev_frame_data : \%frame_data, - $access ? \%next_frame_data : \%frame_data, - \%words_data, -); -- 2.30.2