From: b Date: Mon, 12 Feb 2024 22:14:10 +0000 (+0000) Subject: keep just the old logs tool as standalone version now X-Git-Tag: v1.0.0 X-Git-Url: http://bicyclesonthemoon.info/git-projects/?a=commitdiff_plain;h=0dbfee0eda541c8451d116ee7b1b81f10d7390cf;p=botm%2Foldlogs keep just the old logs tool as standalone version now --- 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 d4aea7f..0000000 Binary files a/botmlogo.png and /dev/null differ diff --git a/bsta.1.conf b/bsta.1.conf deleted file mode 100644 index 43791a2..0000000 --- a/bsta.1.conf +++ /dev/null @@ -1,15 +0,0 @@ -# bsta.conf is automatically generated from bsta.1.conf - -ScriptAlias ###CONF_CGI_2WORDS; ###CONF_BIN_2WORDS; -ScriptAlias ###CONF_CGI_ATTACH; ###CONF_BIN_ATTACH; -ScriptAlias ###CONF_CGI_BBCODE; ###CONF_BIN_BBCODE; -ScriptAlias ###CONF_CGI_COIN; ###CONF_BIN_COIN; -ScriptAlias ###CONF_CGI_FRAME; ###CONF_BIN_FRAME; -ScriptAlias ###CONF_CGI_GOTO; ###CONF_BIN_GOTO; -ScriptAlias ###CONF_CGI_INFO; ###CONF_BIN_INFO; -ScriptAlias ###CONF_CGI_VIEWER; ###CONF_BIN_VIEWER; -ScriptAlias ###CONF_CGI_WORDS; ###CONF_BIN_WORDS; - - - 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, -);