From: b Date: Mon, 5 Feb 2024 23:24:17 +0000 (+0000) Subject: input validation; goto form; show version; 2 words password X-Git-Tag: v1.0.0~1 X-Git-Url: http://bicyclesonthemoon.info/git-projects/?a=commitdiff_plain;h=ea898209fc032b021704c3c7484c7d69580a2f8d;p=botm%2Foldlogs input validation; goto form; show version; 2 words password --- diff --git a/2words.1.pl b/2words.1.pl index 3b8bdfa..1bc2d74 100644 --- a/2words.1.pl +++ b/2words.1.pl @@ -29,11 +29,10 @@ use Encode ('encode', 'decode'); use botm_common ( 'HTTP_STATUS', 'http_header_status', 'http_header_allow', - 'read_data_file', 'write_data_file', 'merge_url', 'read_header_env', 'html_entity_encode_dec', - 'url_query_decode', + 'url_query_decode', 'url_query_encode', 'open_encoded' ); use bsta_lib ( @@ -44,16 +43,16 @@ use bsta_lib ( 'print_html_head_start', 'print_html_head_end', 'print_html_body_start', 'print_html_body_end', 'write_index', - 'get_remote_addr', + 'get_remote_addr', 'get_password', 'merge_settings', - 'ong' + '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_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_WEBSITE_NAME: WEBSITE_NAME = Bicycles on the Moon @@ -94,14 +93,13 @@ my $intf_state; my $intf_pass; my $intf_pause; my $intf_mode; -my $story_i_path; my $fh; my $story_lock; my @story_lines; my $ong_state; my $page; -my $cmd_clear; -my $cmd_clear_all; +my $password; +my $password_ok; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; @@ -130,15 +128,19 @@ if ($method eq 'POST') { $IP = get_remote_addr(); $page = get_id(\%cgi); +$password = get_password(\%cgi); if ($cgi{'words'} ne '') { $words = $cgi{'words'}; } -%settings = read_data_file(DATA_SETTINGS_PATH()); -%state = read_data_file(DATA_STATE_PATH()); +%settings = read_settings(); +%state = read_state(); $ong_state = int($state{'state'}); -$cmd_clear = $settings{'password'}.' clear'; -$cmd_clear_all = $settings{'password'}.' clearall'; + +$password_ok = ($password eq $settings{'password'}); +if ($password_ok) { + $IP .= ' OK'; +} $story_lock=0; if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { @@ -146,7 +148,7 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { if (flock($fh,2)) { $story_lock=2; } - %story = read_data_file($fh); + %story = read_story($fh); if ($story{'lastip'} =~ /^.+$/) { $last_IP=$&; @@ -172,13 +174,13 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { if ( ($intf_state < 0) || ( ($method eq 'POST') && ( - ($words eq $cmd_clear) || - ($words eq $cmd_clear_all) + ($cgi{'clear'} ne '') || + ($cgi{'clear_all'} ne '') ) ) ) { if ( - ($words eq $cmd_clear_all) || + ($cgi{'clear_all'} ne '') || ($intf_state < -1) ) { $story{'id'} = 0; @@ -198,28 +200,38 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { 0 # pause ); } - write_data_file($fh, \%story); + write_story($fh, \%story); } if (($words ne '') && ($method eq 'POST')) { - if (!$turn) { + 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]*)$/) { + 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 '') + ($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) { + 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).'.'; } @@ -233,10 +245,12 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { if ($cgi{'next'} ne '') { # start next game - if (split(/\r?\n/,$story{'content'}) >= (STORY_LENGTH-1)) { + if ( + $password_ok || + (split(/\r?\n/,$story{'content'}) >= (STORY_LENGTH-1)) + ) { # store finished game - $story_i_path = DATA_STORY_PATH.$story_id; - write_data_file($story_i_path, \%story); + write_story($story_id, \%story); # init new game $new_story{'id' } = $story_id + 1; $new_story{'letter' } = ''; @@ -260,11 +274,11 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { ); } # save new game - write_data_file($fh, \%new_story); + write_story($fh, \%new_story); } else { $message = 'To early to finish this wordgame.'; - write_data_file($fh, \%story); + write_story($fh, \%story); } } else { @@ -354,7 +368,7 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { } } } - write_data_file($fh, \%story); + write_story($fh, \%story); } } } @@ -379,7 +393,7 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) { $intf_mode, $intf_pause ); - write_data_file($fh, \%story); + write_story($fh, \%story); } @story_lines = split(/\r?\n/, $story{'content'}); if(@story_lines & 1) { @@ -401,7 +415,7 @@ if($method eq 'HEAD') { exit; } -my $max_page = int(($story_id - FIRSTPAGE_LENGTH - 1) / PAGE_LENGTH) + 1; +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'}); @@ -500,6 +514,20 @@ my $intf_img = merge_url( {'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); @@ -556,7 +584,7 @@ if ($page == 0) { print ' '.$_message.''."\n"; } - if ($turn) { + if ($turn || $password_ok) { print '
'."\n"; if ($message eq '') { if ($story{"content"} eq '') { @@ -568,9 +596,14 @@ if ($page == 0) { } print ' '."\n"; print ' '."\n"; - if (@story_lines >= (STORY_LENGTH-1)) { + if ((@story_lines >= (STORY_LENGTH-1)) || $password_ok ) { print ' '."\n"; } + if ($password_ok) { + print ' '."\n"; + print ' '."\n"; + print ' '."\n"; + } print '
'."\n"; } else { @@ -610,8 +643,7 @@ print '
'."\n"; print '
'."\n"; for (my $i = $id_start; $i > $id_stop; --$i) { - $story_i_path = DATA_STORY_PATH.$i; - %new_story = read_data_file($story_i_path); + %new_story = read_story($i); print '

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

'."\n"; } print '
'."\n"; diff --git a/attach.1.pl b/attach.1.pl index 151dddc..cb34f63 100644 --- a/attach.1.pl +++ b/attach.1.pl @@ -30,7 +30,6 @@ use botm_common ( 'HTTP_STATUS', 'read_header_env', 'url_query_decode', - 'read_data_file', 'join_path', 'merge_url', 'open_encoded', 'stat_encoded', @@ -41,18 +40,14 @@ use bsta_lib ( 'merge_settings', 'get_id', 'get_password', 'fail_method', 'fail_content_type', 'fail_attachment', 'fail_500', - 'redirect' + '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_DATA_ATTACH_PATH: DATA_ATTACH_PATH = /botm/data/bsta/a -###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state - ###PERL_WWW_PATH: WWW_PATH = /botm/www/1190/bsta/ binmode STDIN, ':encoding(UTF-8)'; @@ -112,9 +107,9 @@ if ($method eq 'POST') { $ID = get_id( \%cgi); $password = get_password(\%cgi); -%settings = read_data_file(DATA_SETTINGS_PATH()); -%state = read_data_file(DATA_STATE_PATH()); -%file_data = read_data_file(DATA_ATTACH_PATH().$ID); +%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'}); diff --git a/bbcode.1.pl b/bbcode.1.pl index ee88ab1..28e5e6d 100644 --- a/bbcode.1.pl +++ b/bbcode.1.pl @@ -29,9 +29,7 @@ use Encode ('encode', 'decode'); use botm_common ( 'HTTP_STATUS', 'read_header_env', - 'read_data_file', 'url_query_decode', - 'join_path', 'merge_url', 'http_header_status' ); @@ -40,19 +38,16 @@ use bsta_lib ( 'fail_method', 'fail_content_type', 'get_frame', 'get_password', 'merge_settings', - 'eval_bb', 'bb_to_bbcode' + 'eval_bb', 'bb_to_bbcode', + 'get_frame_file', + 'read_frame_data', 'read_default', 'read_noaccess', + 'read_settings', 'read_state' ); -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - ###PERL_CGI_PATH: CGI_PATH = /bsta/ ###PERL_CGI_VIEWER_PATH: CGI_VIEWER_PATH = /bsta/v ###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta/ -###PERL_DATA_DEFAULT_PATH: DATA_DEFAULT_PATH = /botm/data/bsta/default -###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_SCHEME: SCHEME = http ###PERL_WEBSITE: WEBSITE = 1190.bicyclesonthemoon.info @@ -110,9 +105,9 @@ if ($method eq 'POST') { $frame = get_frame(\%cgi); $password = get_password(\%cgi); -%settings = read_data_file(DATA_SETTINGS_PATH()); -%default = read_data_file(DATA_DEFAULT_PATH()); -%state = read_data_file(DATA_STATE_PATH()); +%settings = read_settings(); +%default = read_default(); +%state = read_state(); $ong_state = int($state{'state'}); $last_frame = int($state{'last'}); @@ -122,9 +117,7 @@ $password_ok = ($password eq $settings{'password'}); if ($frame < 0) { $frame = $last_frame + $frame +1; } -$frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame); -%frame_data = read_data_file($frame_data_path); -%frame_data = merge_settings(\%default, \%frame_data); +%frame_data = read_frame_data($frame, \%default); if ( $password_ok || ( @@ -137,18 +130,9 @@ if ( } else { $access=0; - %frame_data = read_data_file(DATA_NOACCESS_PATH()); - %frame_data = merge_settings(\%default, \%frame_data); -} -if ($frame_data{'frame'} ne '') { - $frame_file = $frame_data{'frame'}; -} -else { - $frame_file = sprintf( - $settings{'frame'}, - $frame, $frame_data{'ext'} - ); + %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) { diff --git a/bsta.css b/bsta.css index b1ae221..da52470 100644 --- a/bsta.css +++ b/bsta.css @@ -6,6 +6,7 @@ html color: #000000; text-align: center; } + a { border-color: #0057af; @@ -92,7 +93,6 @@ div#title border: 0px; margin: 0px; } - div.title { text-align: center; @@ -110,7 +110,6 @@ h1#titletext border: 0px; padding: 0px; } - h1.titletext { margin: 0px; @@ -146,17 +145,23 @@ img#frame 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; @@ -166,32 +171,24 @@ img#frame.bftf background-color: #d9ecff; } -img#frame:hover -{ - border-color: #bb6622; -} - 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; @@ -210,7 +207,6 @@ div#undertext margin: 0px; border: 0px; } - div.undertext { text-align: left; @@ -235,19 +231,16 @@ div.fq 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; @@ -259,31 +252,26 @@ div.opomba 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; @@ -319,7 +307,6 @@ div#underlinks border: 0px; font-family: monospace; } - div.underlinks { text-align: left; @@ -333,7 +320,6 @@ span.inp { animation: inp 2380ms step-start infinite; } - @keyframes inp { 50% { opacity: 0.0;} @@ -350,11 +336,14 @@ input.intx font-family: monospace; /* font-size: 150%; */ } - input.intx:focus { border-color: #bb6622; } +input.intx:hover +{ + border-color: #bb6622; +} input.intxc { @@ -368,11 +357,14 @@ input.intxc width: 100%; /* font-size: 150%; */ } - input.intxc:focus { border-color: #bb6622; } +input.intxc:hover +{ + border-color: #bb6622; +} /* table.intxc { @@ -390,11 +382,14 @@ textarea.inta margin: 2px; resize: none; } - textarea.inta:focus { border-color: #bb6622; } +textarea.inta:hover +{ + border-color: #bb6622; +} input.inbt { @@ -407,11 +402,14 @@ input.inbt font-family: monospace; /* font-size: 150%; */ } - input.inbt:focus { border-color: #bb6622; } +input.inbt:hover +{ + border-color: #bb6622; +} input.hl { background:none!important; @@ -428,6 +426,14 @@ input.hl:hover { border-color: #bb6622; color: #bb6622; } +form.hl { + display: inline +} + +form.goto { + clear: both; + display: inline +} .br { diff --git a/bsta_lib.1.pm b/bsta_lib.1.pm index 7b8c37d..7545a90 100644 --- a/bsta_lib.1.pm +++ b/bsta_lib.1.pm @@ -19,7 +19,6 @@ # TODO: FQ NBSP ? # TODO: DEBUG -# TODO: timer JS # TODO: BB & INFO indent package bsta_lib; @@ -47,6 +46,14 @@ our @EXPORT_OK = ( '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' ); @@ -72,6 +79,7 @@ use botm_common ( ###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 @@ -91,6 +99,7 @@ use botm_common ( ###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/ @@ -949,8 +958,7 @@ sub print_goto { $ongtime = $goto_list->{'ongtime-'.$frame}; $title = $goto_list->{'title-' .$frame}; if (($ongtime eq '') && ($title eq '')) { - my $frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame); - my %frame_data = read_data_file($frame_data_path); + my %frame_data = read_frame_data($frame); $ongtime = $frame_data{'ongtime'}; $title = $frame_data{'title'}; unless (keys %frame_data) { @@ -1034,6 +1042,7 @@ sub print_viewer_page { 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'}); @@ -1137,7 +1146,6 @@ sub print_viewer_page { my $password_query; my $base_url = CGI_PATH(); - my $goto_url = CGI_GOTO_PATH(); my $timer_url = CGI_TIMER_PATH(); my $viewer_full_url = merge_url( {'scheme' => SCHEME(), 'host' => WEBSITE()}, @@ -1164,6 +1172,16 @@ sub print_viewer_page { {'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; @@ -1171,15 +1189,7 @@ sub print_viewer_page { $viewer_prev_url = $viewer_0_url; } else { - if ($prev_frame_data->{'page'} ne '') { - $page_file = $prev_frame_data->{'page'}; - } - else { - $page_file = sprintf( - $settings->{'frame'}, - $prev_frame, 'htm' - ); - } + $page_file = get_page_file($prev_frame, $prev_frame_data, $settings); if (_x_encoded('-f', join_path(PATH_SEPARATOR(), WWW_PATH() , $page_file) )) { @@ -1190,15 +1200,7 @@ sub print_viewer_page { } } if ($next_frame < $last_frame) { - if ($next_frame_data->{'page'} ne '') { - $page_file = $next_frame_data->{'page'}; - } - else { - $page_file = sprintf( - $settings->{'frame'}, - $next_frame, 'htm' - ); - } + $page_file = get_page_file($next_frame, $next_frame_data, $settings); if (_x_encoded('-f', join_path(PATH_SEPARATOR(), WWW_PATH() , $page_file) )) { @@ -1208,7 +1210,10 @@ sub print_viewer_page { ); } } - if (_x_encoded('-f',WWW_GOTO_PATH())) { + if ( + $goto && + (_x_encoded('-f',WWW_GOTO_PATH())) + ) { $goto_url = CGI_LIST_PATH(); } } @@ -1255,15 +1260,7 @@ sub print_viewer_page { my $frame_next_url; my $frame_normal_url; my $frame_full_url; - if ($frame_data->{'frame'} ne '') { - $frame_file = $frame_data->{'frame'}; - } - else { - $frame_file = sprintf( - $settings->{'frame'}, - $frame, $frame_data->{'ext'} - ); - } + $frame_file = get_frame_file($frame, $frame_data, $settings); $frame_normal_url = merge_url( {'path' => CGI_PATH()}, {'path' => $frame_file} @@ -1284,34 +1281,24 @@ sub print_viewer_page { {'path' => $prev_frame} ); } - elsif ($prev_frame_data->{'frame'} ne '') { + else { $frame_prev_url = merge_url( {'path' => CGI_PATH()}, - {'path' => $prev_frame_data->{'frame'}} + {'path' => get_frame_file($prev_frame, $prev_frame_data, $settings)} ); } - else { - $frame_prev_url = merge_url(CGI_PATH(), sprintf( - $settings->{'frame'}, $prev_frame, $prev_frame_data->{'ext'} - )); - } if ($nextframe_indirect) { $frame_next_url = merge_url( {'path' => CGI_FRAME_PATH()}, {'path' => $next_frame} ); } - elsif ($next_frame_data->{'frame'} ne '') { + else { $frame_next_url = merge_url( {'path' => CGI_PATH()}, - {'path' => $next_frame_data->{'frame'}} + {'path' => get_frame_file($next_frame, $next_frame_data, $settings)} ); } - else { - $frame_next_url = merge_url(CGI_PATH(), sprintf( - $settings->{'frame'}, $next_frame, $next_frame_data->{'ext'} - )); - } if ($password_ok) { $password_query = url_query_encode({'p', $settings->{'password'}}); @@ -1334,22 +1321,24 @@ sub print_viewer_page { $frame_next_url= merge_url($frame_next_url , {'query' => $password_query, 'append_query' => 1, 'preserve_fragment' => 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 $_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); @@ -1369,14 +1358,8 @@ sub print_viewer_page { unless (($access) && ($frame < $last_frame)) { $frame_data->{'page'} = ''; } - elsif ($frame == 0) { - $frame_data->{'page'} = 'index.htm'; - } else { - $frame_data->{'page'} = sprintf( - $settings->{'frame'}, - $frame, 'htm' - ); + $frame_data->{'page'} = get_page_file($frame, $frame_data, $settings); } } } @@ -1514,7 +1497,10 @@ sub print_viewer_page { } print $fh 'GOTO'."\n"; print $fh ' '."\n "; - if ($text_mode == TEXT_MODE->{'normal'}) { + if ( + ($text_mode == TEXT_MODE->{'normal'}) && + (!$goto) + ){ if ($show_words) { print $fh ''.$words_link_text.' | '; } @@ -1527,6 +1513,25 @@ sub print_viewer_page { print $fh "\n \n"; print $fh "
\n"; + + if ($goto) { + print $fh ' \n"; + } + print $fh " \n"; if (($text_mode == TEXT_MODE->{'words'}) && $show_words) { @@ -1597,8 +1602,8 @@ sub print_comments { $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 $_password = html_entity_encode_dec($settings->{'password'}, 1); my $_older_url = html_entity_encode_dec($older_url, 1); my $_newer_url = html_entity_encode_dec($newer_url, 1); @@ -1634,8 +1639,7 @@ sub print_comments { if ($post_count > 0) { for (my $i=$id_start; $i<$id_stop; ++$i) { my $ID = $words_data->{'content'}->[$i]; - my $post_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $ID); - my %post_data = read_data_file($post_path); + my %post_data = read_words($ID); my $post_time = int($post_data{'posttime'}); my $edit_time = int($post_data{'edittime'}); @@ -1786,20 +1790,14 @@ sub write_index { # normal running story if ($ong_state > STATE->{'inactive'}) { - my %frame_data = read_data_file(join_path(PATH_SEPARATOR(), DATA_PATH(), 0)); - my %next_frame_data= read_data_file(join_path(PATH_SEPARATOR(), DATA_PATH(), 1)); - my %default = read_data_file(DATA_DEFAULT_PATH()); - my %words_data = read_data_file( - join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), 0), - '', # encoding - 0, # no header + 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 - 1, # as list ); - %frame_data = merge_settings(\%default, \%frame_data); - %next_frame_data= merge_settings(\%default, \%next_frame_data); - $r = print_viewer_page( $fh, { @@ -1812,7 +1810,8 @@ sub write_index { 'static' => 1, 'show_command' => 1, 'text_mode' => TEXT_MODE->{'normal'}, - 'words_page' => 0 # not relevant + 'words_page' => 0, # not relevant + 'goto' => 0 }, $state, $settings, @@ -1874,13 +1873,10 @@ sub write_index { } # the launch index else { - my %frame_data = read_data_file(join_path(PATH_SEPARATOR(), DATA_PATH(), 0)); - my %next_frame_data= read_data_file(join_path(PATH_SEPARATOR(), DATA_PATH(), 1)); - my %default = read_data_file(DATA_DEFAULT_PATH()); - my %coin_data = read_data_file(DATA_COIN_PATH()); - - %frame_data = merge_settings(\%default, \%frame_data); - %next_frame_data= merge_settings(\%default, \%next_frame_data); + 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( @@ -1895,7 +1891,8 @@ sub write_index { 'static' => 1, 'show_command' => 1, 'text_mode' => TEXT_MODE->{'normal'}, - 'words_page' => 0 # not relevant + 'words_page' => 0, # not relevant + 'goto' => 0 }, $state, $settings, @@ -2051,7 +2048,7 @@ sub write_static_viewer_page { %state = (ref ($state_ref)) ? %$state_ref : - read_data_file(DATA_STATE_PATH()); + read_state(); my $ong_state = int($state{'state'}); my $last_frame = int($state{'last'}); @@ -2071,55 +2068,38 @@ sub write_static_viewer_page { %settings = (ref ($settings_ref)) ? %$settings_ref : - read_data_file(DATA_SETTINGS_PATH()); + read_settings(); %default = (ref ($default_ref)) ? %$default_ref : - read_data_file(DATA_DEFAULT_PATH()); + read_default(); %frame_data = (ref ($frame_data_ref)) ? %$frame_data_ref : - read_data_file(join_path(PATH_SEPARATOR(), DATA_PATH(), $frame)); + read_frame_data($frame); %prev_frame_data = (ref ($prev_frame_data_ref)) ? %$prev_frame_data_ref : ( ($prev_frame >= 0) ? - read_data_file(join_path(PATH_SEPARATOR(), DATA_PATH(), $prev_frame)) : + read_frame_data($prev_frame) : %default ); %next_frame_data = (ref ($next_frame_data_ref)) ? - %$next_frame_data_ref : ( - (($next_frame < $last_frame) || ( - ($next_frame <= $last_frame) && - ($next_frame >= STATE->{'end'}) - )) ? - read_data_file(join_path(PATH_SEPARATOR(), DATA_PATH(), $next_frame)) : - %default - ); - - %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); + %$next_frame_data_ref : + read_frame_data($next_frame); %words_data = (ref ($words_data_ref)) ? %$words_data_ref : - read_data_file( - join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $frame), # file - '', # encoding - 0, # no header + read_words_list( + $frame, # frame ID 1, # header only - 1, # as list; not relevant ); - if ($frame_data{'page'} ne '') { - $file = $frame_data{'page'} - } - else { - $file = sprintf( - $settings{'frame'}, - $frame, 'htm' - ); - } + %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( @@ -2135,6 +2115,7 @@ sub write_static_viewer_page { 'show_command' => 1, 'text_mode' => TEXT_MODE->{'normal'}, 'words_page' => 0, # not relevant + 'goto' => 0 }, \%state, \%settings, @@ -2153,13 +2134,13 @@ sub write_static_goto { %state = (ref ($state_ref)) ? %$state_ref : - read_data_file(DATA_STATE_PATH()); + read_state(); %settings = (ref ($settings_ref)) ? %$settings_ref : - read_data_file(DATA_SETTINGS_PATH()); + read_settings(); %goto_list = (ref ($goto_ref)) ? %$goto_ref : - read_data_file(DATA_SETTINGS_PATH()); + read_goto(); return print_goto( WWW_GOTO_PATH(), @@ -2232,32 +2213,22 @@ sub ong { else { %settings = (ref ($settings_ref)) ? %$settings_ref : - read_data_file(DATA_SETTINGS_PATH()); - %default = (ref ($default_ref)) ? - %$default_ref : - read_data_file(DATA_DEFAULT_PATH()); + 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_data_file($frame_data_path); + read_frame_data($frame_data_path); %frame_full_data = merge_settings(\%default, \%frame_data); - @files = ( - ($frame_full_data{'frame'} ne '') ? - $frame_full_data{'frame'} : - sprintf( - $settings{'frame'}, - $frame, $frame_full_data{'ext'} - ) - , - ); + @files = (get_frame_file($frame, \%frame_full_data, \%settings), ); unless ($cfrt) { %goto_list = (ref ($goto_ref)) ? %$goto_ref : - read_data_file(DATA_LIST_PATH()); + read_goto(); for (my $i=0; ;$i+=1) { - my %file_data = read_data_file(DATA_ATTACH_PATH().$i); + my %file_data = read_attachment($i); if ($file_data{'frame'} eq '') { last; } @@ -2287,7 +2258,7 @@ sub ong { $write_data = 1; } if ($write_data) { - $r = write_data_file($frame_data_path, \%frame_data); + $r = write_frame_data($frame_data_path, \%frame_data); unless ($r) { print STDERR "fail writing $frame_data_path\n"; if ($print) { @@ -2298,7 +2269,7 @@ sub ong { } $goto_list{'title-' .$frame} = $frame_full_data{'title'}; $goto_list{'ongtime-'.$frame} = $frame_full_data{'ongtime'}; - $r = write_data_file(DATA_LIST_PATH(), \%goto_list); + $r = write_goto('', \%goto_list); unless ($r) { print STDERR "fail writing ".DATA_LIST_PATH()."\n"; if ($print) { @@ -2327,4 +2298,637 @@ sub ong { 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 index 1fd8073..90ea637 100644 --- a/chat.1.pl +++ b/chat.1.pl @@ -29,7 +29,6 @@ use Encode ('encode', 'decode'); ###PERL_LIB: use lib /botm/lib/bsta use botm_common ( 'HTTP_STATUS', - 'read_data_file', 'write_data_file', 'read_header_env', 'url_query_decode', 'url_query_encode', 'merge_url', @@ -44,7 +43,9 @@ use bsta_lib ( 'print_html_start', 'print_html_end', 'print_html_head_start', 'print_html_head_end', 'print_html_body_start', 'print_html_body_end', - 'merge_settings' + 'merge_settings', + 'read_chat', 'write_chat', + 'read_coincidence', 'read_settings', 'read_state' ); use File::Copy; @@ -52,9 +53,6 @@ use File::Copy; ###PERL_CGI_COIN_PATH: CGI_COIN_PATH = /bsta/coin ###PERL_DATA_CHAT_PATH: DATA_CHAT_PATH = /botm/data/bsta/chat -###PERL_DATA_COIN_PATH: DATA_COIN_PATH = /botm/data/bsta/coincidence -###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state ###PERL_WEBSITE_NAME: WEBSITE_NAME = Bicycles on the Moon @@ -118,9 +116,9 @@ $IP = get_remote_addr(); $page = get_id(\%cgi, -1); $password = get_password(\%cgi); -%coin = read_data_file(DATA_COIN_PATH()); -%settings = read_data_file(DATA_SETTINGS_PATH()); -%state = read_data_file(DATA_STATE_PATH()); +%coin = read_coincidence(); +%settings = read_settings(); +%state = read_state(); $password_ok = ($password eq $settings{'password'}); @@ -141,7 +139,7 @@ foreach my $action_id ('join', 'leave', 'nopost', 'file') { if ($page < 0) { if (open_encoded($fh, "+<", DATA_CHAT_PATH())) { if (flock($fh, 2)) { - %chat = read_data_file($fh); + %chat = read_chat($fh); $chat_state = int($chat{'state'}); $chat_id = int($chat{'id'}); @@ -167,7 +165,7 @@ if ($page < 0) { $chat_state = CHAT_STATE->{'active'}; $chat{'state'} = $chat_state; } - write_data_file($fh, \%chat); + write_chat($fh, \%chat); } else { $status = HTTP_STATUS->{'bad_request'}; @@ -193,7 +191,7 @@ if ($page < 0) { $chat_state = CHAT_STATE->{'ready'}; $chat{'state'} = $chat_state; } - write_data_file($fh, \%chat); + write_chat($fh, \%chat); } elsif ($words eq '') { $status = HTTP_STATUS->{'bad_request'}; @@ -223,12 +221,12 @@ if ($page < 0) { if ($username =~ /^[A-Za-z]*$/) { $chat{'content'} .= 'leave@'.$username.': '.$words."\n"; if ($username ne '') { - write_data_file($fh, \%chat); + write_chat($fh, \%chat); } else { my %new_chat; if ($chat_state > 1) { - write_data_file(DATA_CHAT_PATH.$chat_id, \%chat); + write_chat($chat_id, \%chat); $new_chat{'id'} = $chat_id+1; } else { @@ -236,7 +234,7 @@ if ($page < 0) { } $new_chat{'state'} = CHAT_STATE->{'disconnected'}; $new_chat{'content'} = ''; - write_data_file($fh, \%new_chat); + write_chat($fh, \%new_chat); } } else { @@ -259,7 +257,7 @@ if ($page < 0) { $chat_state = CHAT_STATE->{'active'}; $chat{'state'} = $chat_state; } - write_data_file($fh, \%chat); + write_chat($fh, \%chat); } else { $status = HTTP_STATUS->{'bad_request'}; @@ -291,10 +289,10 @@ if ($page < 0) { # old chat archive else { $chat_id = $page; - %chat = read_data_file(DATA_CHAT_PATH()); + %chat = read_chat(); $last_id = int($chat{'id'}); if ($chat_id < $last_id) { - %chat = read_data_file(DATA_CHAT_PATH.$page); + %chat = read_chat($page); $chat_state = int($chat{'state'}); @chat_lines = split(/\r?\n/, $chat{'content'}); } @@ -337,11 +335,11 @@ if ($password_ok) { $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 $_password = html_entity_encode_dec($settings{'password'}, 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); diff --git a/frame.1.pl b/frame.1.pl index 9bea1c2..a0a81fd 100644 --- a/frame.1.pl +++ b/frame.1.pl @@ -30,7 +30,6 @@ use botm_common ( 'HTTP_STATUS', 'read_header_env', 'url_query_decode', - 'read_data_file', 'join_path', 'merge_url', 'open_encoded', 'stat_encoded', @@ -40,20 +39,16 @@ use bsta_lib ( 'STATE', 'INTF_STATE', 'fail_method', 'fail_content_type', 'fail_open_file', 'fail_500', 'redirect', 'get_frame', 'get_password', - 'merge_settings' + '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_DATA_DEFAULT_PATH: DATA_DEFAULT_PATH = /botm/data/bsta/default -###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_WWW_PATH: WWW_PATH = /botm/www/1190/bsta/ binmode STDIN, ':encoding(UTF-8)'; @@ -79,7 +74,6 @@ my $IP; my $access; my $try_onged; my $frame_path; -my $frame_data_path; my $frame_file; my $fh; my $buffer; @@ -114,9 +108,9 @@ if ($method eq 'POST') { $frame = get_frame(\%cgi); $password = get_password(\%cgi); -%settings = read_data_file(DATA_SETTINGS_PATH()); -%default = read_data_file(DATA_DEFAULT_PATH()); -%state = read_data_file(DATA_STATE_PATH()); +%settings = read_settings(); +%default = read_default(); +%state = read_state(); $ong_state = int($state{'state'}); $last_frame = int($state{'last'}); @@ -141,7 +135,7 @@ elsif ( ($ong_state == STATE->{'inactive'}) && ($frame == 0) ) { - my %story = read_data_file(DATA_STORY_PATH()); + my %story = read_story(); if ( (int($story{'pass'}) == 1) && (int($story{'state'}) == INTF_STATE->{'>|'}) @@ -158,23 +152,12 @@ $try_onged = ( ); if ($access) { - $frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame); - %frame_data = read_data_file($frame_data_path); - %frame_data = merge_settings(\%default, \%frame_data); -} -else { - %frame_data = read_data_file(DATA_NOACCESS_PATH()); - %frame_data = merge_settings(\%default, \%frame_data); -} -if ($frame_data{'frame'} ne '') { - $frame_file = $frame_data{'frame'}; + %frame_data = read_frame_data($frame, \%default); } else { - $frame_file = sprintf( - $settings{'frame'}, - $frame, $frame_data{'ext'} - ); + %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); diff --git a/goto.1.pl b/goto.1.pl index 80dcf16..37feb23 100644 --- a/goto.1.pl +++ b/goto.1.pl @@ -28,7 +28,6 @@ use Encode ('encode', 'decode'); ###PERL_LIB: use lib /botm/lib/bsta use botm_common ( 'read_header_env', - 'read_data_file', 'url_query_decode', '_x_encoded' ); @@ -38,20 +37,14 @@ use bsta_lib ( 'redirect', 'get_password', 'print_goto', - 'merge_settings' + 'merge_settings', + 'read_settings', 'read_state', 'read_goto' ); -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - ###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_DATA_PATH: DATA_PATH = /botm/data/bsta/ -###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state -###PERL_DATA_LIST_PATH: DATA_LIST_PATH = /botm/data/bsta/list - ###PERL_WWW_GOTO_PATH: WWW_GOTO_PATH = /botm/www/1190/bsta/goto.htm ###PERL_WEBSITE_NAME: WEBSITE_NAME = Bicycles on the Moon @@ -109,9 +102,9 @@ if ($no_cgi) { $password = get_password(\%cgi); -%settings = read_data_file(DATA_SETTINGS_PATH()); -%state = read_data_file(DATA_STATE_PATH()); -%goto_list = read_data_file(DATA_LIST_PATH()); +%settings = read_settings(); +%state = read_state(); +%goto_list = read_goto(); $password_ok = ($password eq $settings{'password'}); diff --git a/info.1.pl b/info.1.pl index d5c0ec8..3778092 100644 --- a/info.1.pl +++ b/info.1.pl @@ -30,27 +30,20 @@ use botm_common ( 'HTTP_STATUS', 'http_header_status', 'read_header_env', - 'read_data_file', 'write_data_file', - 'url_query_decode', - 'join_path' + 'write_data_file', + 'url_query_decode' ); use bsta_lib ( 'STATE', 'fail_method', 'fail_content_type', 'get_password', - 'merge_settings' + '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' ); -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta -###PERL_DATA_ATTACH_PATH: DATA_ATTACH_PATH = /botm/data/bsta/a -###PERL_DATA_DEFAULT_PATH: DATA_DEFAULT_PATH = /botm/data/bsta/default -###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_WORDS_PATH: DATA_WORDS_PATH = /botm/data/bsta/words/ - binmode STDIN, ':encoding(UTF-8)'; binmode STDOUT, ':encoding(UTF-8)'; binmode STDERR, ':encoding(UTF-8)'; @@ -77,8 +70,6 @@ my $access; my $show_command; my $ongtime; my $timer; -my $info_data_path; -my $next_frame_data_path; my $ong_state; my $last_frame; @@ -118,21 +109,21 @@ elsif ($cgi{'i'} =~ /^.+$/) { elsif ($cgi{'w'} =~ /^.+$/) { $words = $&; } -elsif ($ENV{'PATH_INFO'} =~ /^\/a(.+)$/) { +elsif ($ENV{'PATH_INFO'} =~ /^\/a\/?(.+)$/) { $attachment = int($1); } -elsif ($ENV{'PATH_INFO'} =~ /^\/w(.+)$/) { +elsif ($ENV{'PATH_INFO'} =~ /^\/w\/?(.+)$/) { $words = $1; } -elsif ($ENV{'PATH_INFO'} =~ /^\/f?(.+)$/) { - $frame = int($1); +elsif ($ENV{'PATH_INFO'} =~ /^\/(f\/?)?(.+)$/) { + $frame = int($2); } $password = get_password(\%cgi); -%settings = read_data_file(DATA_SETTINGS_PATH()); -%default = read_data_file(DATA_DEFAULT_PATH()); -%state = read_data_file(DATA_STATE_PATH()); +%settings = read_settings(); +%default = read_default(); +%state = read_state(()); $ong_state = int($state{'state'}); $last_frame = int($state{'last'}); @@ -141,15 +132,19 @@ $password_ok = ($password eq $settings{'password'}); # comment info, not frame if ($words ne '') { - $info_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $words); - %info_data = read_data_file($info_data_path); 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; } } - else { + 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'}); @@ -159,7 +154,7 @@ if ($words ne '') { } # attachment info, not frame elsif ($attachment ne '') { - %info_data = read_data_file(DATA_ATTACH_PATH().$attachment); + %info_data = read_attachment($attachment); $frame = ($info_data{'frame'} ne '') ? int($info_data{'frame'}) : -1; } # frame info @@ -167,12 +162,8 @@ elsif ($frame ne '') { if ($frame < 0) { $frame = $last_frame + $frame +1; } - $info_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame); - $next_frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame+1); - %info_data = read_data_file($info_data_path); - %next_frame_data = read_data_file($next_frame_data_path); - %info_data = merge_settings(\%default, \%info_data); - %next_frame_data = merge_settings(\%default, \%next_frame_data); + %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'}); @@ -237,8 +228,7 @@ else { %info_data = (); } else { - %info_data = read_data_file(DATA_NOACCESS_PATH()); - %info_data = merge_settings(\%default, \%info_data); + %info_data = read_noaccess(\%default); } } if ( @@ -246,17 +236,14 @@ if ( ($words eq '') ) { if ($info_data{'frame'} eq '') { - $info_data{'frame'} = sprintf($settings{'frame'}, $frame, $info_data{'ext'}); + $info_data{'frame'} = get_frame_file($frame, \%info_data, \%settings) } if ($info_data{'page'} eq '') { unless (($access) && ($frame < $last_frame)) { $info_data{'page'} = ''; } - elsif ($frame == 0) { - $info_data{'page'} = 'index.htm'; - } else { - $info_data{'page'} = sprintf($settings{'frame'}, $frame, 'htm'); + $info_data{'page'} = get_page_file($frame, \%info_data, \%settings); } } } diff --git a/ong.1.pl b/ong.1.pl index 6c3ecf3..df5eab0 100644 --- a/ong.1.pl +++ b/ong.1.pl @@ -26,22 +26,16 @@ use Encode ('encode', 'decode'); ###PERL_LIB: use lib /botm/lib/bsta use botm_common ( - 'read_data_file', 'write_data_file', 'open_encoded', - 'join_path' ); use bsta_lib ( 'STATE', 'ong', - 'write_static_viewer_page', 'write_index', 'write_static_goto' + 'write_static_viewer_page', 'write_index', 'write_static_goto', + 'read_default', 'read_frame_data', 'read_settings', 'read_goto', + 'read_state', 'write_state' ); -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta/ -###PERL_DATA_DEFAULT_PATH: DATA_DEFAULT_PATH = /botm/data/bsta/default -###PERL_DATA_LIST_PATH: DATA_LIST_PATH = /botm/data/bsta/list -###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings ###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state binmode STDIN, ':encoding(UTF-8)'; @@ -88,7 +82,7 @@ unless (flock($fh, 2)) { close ($fh); exit; } -%state = read_data_file($fh); +%state = read_state($fh); $ongstate = int($state{'state'}); print 'state: '.$ongstate."\n"; unless ($ongstate > STATE->{'inactive'}) { @@ -105,7 +99,7 @@ unless ($ongtime >= $next_ong) { exit; } -%settings = read_data_file(DATA_SETTINGS_PATH()); +%settings = read_settings(); $static_timer = int($settings{'ongtime'}); $timer = int($settings{'dynamicongtime'}); $last = int($settings{'last'}); @@ -129,11 +123,9 @@ $state{'ongtime'}=$timer; if ($ongstate == STATE->{'ready'}) { print 'next frame: '.$frame."\n"; - %default = read_data_file(DATA_DEFAULT_PATH()); - %frame_data = read_data_file( - join_path(PATH_SEPARATOR(), DATA_PATH(), $frame) - ); - # %goto_list = read_data_file(DATA_LIST_PATH()); + %default = read_default(); + %frame_data = read_frame_data($frame); + # %goto_list = read_goto()); %new_state = %state; $new_state{'last'} = $frame; @@ -144,19 +136,13 @@ if ($ongstate == STATE->{'ready'}) { $new_state{'ongtime'}= $timer; if ($frame >= 1) { - %frame_1_data = read_data_file( - join_path(PATH_SEPARATOR(), DATA_PATH(), $frame-1) - ); + %frame_1_data = read_frame_data($frame-1); } if ($frame >= 2) { - %frame_2_data = read_data_file( - join_path(PATH_SEPARATOR(), DATA_PATH(), $frame-2) - ); + %frame_2_data = read_frame_data($frame-2); } if ($frame >= 3) { - %frame_3_data = read_data_file( - join_path(PATH_SEPARATOR(), DATA_PATH(), $frame-3) - ); + %frame_3_data = read_frame_data($frame-3); } $r = ong ( @@ -223,5 +209,5 @@ if ($ongstate == STATE->{'ready'}) { print "NO ONG\n\n"; } } -write_data_file($fh, \%state); +write_state($fh, \%state); close ($fh); diff --git a/opomba.1.pl b/opomba.1.pl index 4e29a56..639097a 100644 --- a/opomba.1.pl +++ b/opomba.1.pl @@ -29,7 +29,7 @@ use Encode ('encode', 'decode'); use botm_common ( 'HTTP_STATUS', 'read_header_env', 'url_query_decode', - 'read_data_file', 'write_data_file', + 'write_data_file', 'html_entity_encode_dec', 'open_encoded', 'join_path', @@ -47,7 +47,11 @@ use bsta_lib ( 'print_html_body_start', 'print_html_body_end', 'bb_to_html', 'eval_bb', 'merge_settings', - 'write_index', 'write_static_viewer_page' + '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 = / @@ -55,8 +59,6 @@ use bsta_lib ( ###PERL_CGI_VIEWER_PATH: CGI_VIEWER_PATH = /bsta/v ###PERL_CGI_WORDS_PATH: CGI_WORDS_PATH = /bsta/w -###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state ###PERL_DATA_WORDS_PATH: DATA_WORDS_PATH = /botm/data/bsta/words/ ###PERL_LOG_SPAM_PATH: LOG_SPAM_PATH = /botm/log/bsta/words_spam.log @@ -96,8 +98,6 @@ my $remove = 0; my $post = 0; my $quote; my $words_data_path; -my $post_data_path; -my $last_post_data_path; my $index; my $page; my $ong_state; @@ -144,8 +144,8 @@ if ($cgi{'i'} =~ /^.+$/) { } $password = get_password(\%cgi); -%settings = read_data_file(DATA_SETTINGS_PATH()); -%state = read_data_file(DATA_STATE_PATH()); +%settings = read_settings(); +%state = read_state(); $ong_state = int($state{'state'}); $last_frame = int($state{'last'}); @@ -174,8 +174,7 @@ else { } if ($ID ne '') { - $post_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $ID); - %post_data = read_data_file($post_data_path); + %post_data = read_words($ID); if ($post_data{'frame'} ne '') { $frame = int($post_data{'frame'}); } @@ -205,12 +204,9 @@ unless (flock($fh, 2)) { exit output(0, HTTP_STATUS->{'internal_server_error'}, 'Failed locking data file.', 1); } -%words_data = read_data_file( +%words_data = read_words_list( $fh, # file - '', # encoding - 0, # no header 0, # header only - 1 # as list ); @post_list = @{$words_data{'content'}}; @@ -307,14 +303,7 @@ if ($remove) { $words_data{'posts'} = scalar(@post_list); $words_data{'content'} = \@post_list; - $r = write_data_file( - $fh, # file - \%words_data, - '', # encoding - 0, # no header - 0, # header only - 1 # as list - ); + $r = write_words_list($fh, \%words_data); unless ($r) { close($fh); exit output(0, HTTP_STATUS->{'internal_server_error'}, 'Failed writing data file.'); @@ -346,8 +335,7 @@ if ($index eq '') { $page = int($index / COMMENT_PAGE_LENGTH()); if ($index > 0) { $last_ID = $post_list[-1]; - $last_post_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $last_ID); - %last_post_data = read_data_file($last_post_data_path); + %last_post_data = read_words($last_ID); if ( ($cgi{'username'} eq $last_post_data{'name' }) && ($cgi{'words' } eq $last_post_data{'content'}) @@ -364,8 +352,6 @@ if ($index eq '') { $words_data{'posts'} = scalar(@post_list); $words_data{'content'} = \@post_list; -$post_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $ID); - $post_data{'frame'} = $frame; $post_data{'name'} = $cgi{'username'}; $post_data{'password'} = $cgi{'password'}; @@ -384,20 +370,13 @@ if ($post_data{'key'} eq '') { } $post_data{'content'} = $cgi{'words'}; -$r = write_data_file($post_data_path, \%post_data); +$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_data_file( - $fh, # file - \%words_data, - '', # encoding - 0, # no header - 0, # header only - 1 # as list -); +$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); @@ -494,8 +473,7 @@ sub output { $content = $cgi{'words'}; } elsif ($quote ne '') { - my $quote_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $quote); - my %quote_data = read_data_file($quote_data_path); + my %quote_data = read_words($quote); $content = '[quote="'.$quote_data{'name'}.'"]'.$quote_data{'content'}.'[/quote]'; } elsif (($cgi{'edit'} ne '') || $remove) { @@ -505,11 +483,11 @@ sub output { $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 $_password = html_entity_encode_dec($settings{'password'}, 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); diff --git a/reset.1.pl b/reset.1.pl index a7ee374..9aa9541 100644 --- a/reset.1.pl +++ b/reset.1.pl @@ -26,14 +26,16 @@ use Encode ('encode', 'decode'); ###PERL_LIB: use lib /botm/lib/bsta use botm_common ( - 'read_data_file', 'write_data_file', + 'write_data_file', 'opendir_encoded', 'readdir_decoded', 'unlink_encoded', 'join_path' ); use bsta_lib ( 'STATE', 'INTF_STATE', 'CHAT_STATE', 'write_index', - 'merge_settings' + 'merge_settings', + 'get_page_file', 'get_frame_file', + 'read_settings', 'read_default', 'read_frame_data', 'read_attachment', 'read_state' ); binmode STDIN, ':encoding(UTF-8)'; @@ -43,12 +45,9 @@ decode_argv(); ###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta/ -###PERL_DATA_ATTACH_PATH: DATA_ATTACH_PATH = /botm/data/bsta/a ###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_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/state ###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/ @@ -69,7 +68,8 @@ my @remove_list; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; ###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin; -%settings = read_data_file(DATA_SETTINGS_PATH()); +%settings = read_settings(); +%state = read_state(); unless ( ($ARGV[0] ne '') && ( ($ARGV[0] eq $settings{'password'}) || @@ -80,38 +80,22 @@ unless ( exit 1; } -$last_frame = int($settings{'last'}); -%default = read_data_file(DATA_DEFAULT_PATH()); +$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_data_file( - join_path(PATH_SEPARATOR(), DATA_PATH(), $frame) - ); - %frame_data = merge_settings(\%default, \%frame_data); + my %frame_data = read_frame_data($frame, \%default); unless ($frame == 0) { - push @remove_list, ( - ($frame_data{'page'} ne '') ? - $frame_data{'page'} : - sprintf( - $settings{'frame'}, - $frame, 'htm' - ) - ); + push @remove_list, get_page_file($frame, \%frame_data, \%settings); } - push @remove_list, ( - ($frame_data{'frame'} ne '') ? - $frame_data{'frame'} : - sprintf( - $settings{'frame'}, - $frame, $frame_data{'ext'} - ) - ); + 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_data_file(DATA_ATTACH_PATH().$i); + %file_data = read_attachment($i); if ($file_data{'frame'} eq '') { last; } diff --git a/settings-again.txt b/settings-again.txt index e9f7442..8f13d1c 100644 --- a/settings-again.txt +++ b/settings-again.txt @@ -88,5 +88,5 @@ page_length : 16 comment_page_length: 40 story_credits: "BSTA" by Balthasar Szczepański -intf_credits: Online interface © Balthasar Szczepański; AGPL 3 license +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 index 67cbc4a..a02554d 100644 --- a/settings-bsta.txt +++ b/settings-bsta.txt @@ -88,5 +88,5 @@ page_length : 16 comment_page_length: 40 story_credits: "BSTA" by Balthasar Szczepański -intf_credits: Online interface © Balthasar Szczepański; AGPL 3 license +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 5ee085f..40e8d9b 100644 --- a/settings-debug.txt +++ b/settings-debug.txt @@ -88,5 +88,5 @@ page_length : 16 comment_page_length: 4 story_credits: "BSTA" by Balthasar Szczepański -intf_credits: Online interface © Balthasar Szczepański; AGPL 3 license +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.txt b/settings.txt index fb52921..7d809c5 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.0.0 +_version: 1.2.6 _SHEBANG: #!$0 @@ -198,7 +198,7 @@ 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_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) diff --git a/update.1.pl b/update.1.pl index a5f0c5e..8cfba90 100644 --- a/update.1.pl +++ b/update.1.pl @@ -26,23 +26,15 @@ use Encode ('encode', 'decode'); ###PERL_LIB: use lib /botm/lib/bsta use botm_common ( - 'read_data_file', - 'join_path' ); use bsta_lib ( 'STATE', 'ong', - 'write_index', 'write_static_viewer_page', 'write_static_goto' + 'write_index', 'write_static_viewer_page', 'write_static_goto', + 'read_frame_data', 'read_default', 'read_words_list', + 'read_settings', 'read_state' ); -###PERL_PATH_SEPARATOR: PATH_SEPARATOR = / - -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta/ -###PERL_DATA_DEFAULT_PATH: DATA_DEFAULT_PATH = /botm/data/bsta/default -###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings -###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state -###PERL_DATA_WORDS_PATH: DATA_WORDS_PATH = /botm/data/bsta/words/ - binmode STDIN, ':encoding(UTF-8)'; binmode STDOUT, ':encoding(UTF-8)'; binmode STDERR, ':encoding(UTF-8)'; @@ -51,9 +43,9 @@ decode_argv(); my $time = time(); srand ($time-$$); -my %settings = read_data_file(DATA_SETTINGS_PATH()); -my %default = read_data_file(DATA_DEFAULT_PATH()); -my %state = read_data_file(DATA_STATE_PATH()); +my %settings = read_settings(); +my %default = read_default(); +my %state = read_state(); my %all_frame_data = (); my %all_words_data = (); @@ -173,9 +165,7 @@ sub get_frame_data { return $r; } - my %frame_data = read_data_file( - join_path(PATH_SEPARATOR(), DATA_PATH(), $f) - ); + my %frame_data = read_frame_data($f); $all_frame_data{$f} = \%frame_data; return \%frame_data; } @@ -197,15 +187,9 @@ sub get_words_data { return $r; } - my %frame_data = read_data_file( - join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $f), - '', # encoding, - 0, # no header - 1, # header only - 1, # as list; not relevant - ); - $all_words_data{$f} = \%frame_data; - return \%frame_data; + my %words_data = read_words_list($f, 1); + $all_words_data{$f} = \%words_data; + return \%words_data; } sub make_static_page { @@ -216,10 +200,7 @@ sub make_static_page { my $f = int($id); unless ( ($f >= 0) && ( - ($f < $last_frame-1) || ( - ($ong_state >= STATE->{'ready'}) && - ($f <= $last_frame-1) - ) || ( + ($f < $last_frame) || ( ($ong_state >= STATE->{'end'}) && ($f <= $last_frame) ) diff --git a/viewer.1.pl b/viewer.1.pl index 280a0f9..c7d74d9 100644 --- a/viewer.1.pl +++ b/viewer.1.pl @@ -29,7 +29,6 @@ use Encode ('encode', 'decode'); use botm_common ( 'HTTP_STATUS', 'read_header_env', - 'read_data_file', 'write_data_file', 'url_query_decode', 'join_path', 'open_encoded', '_x_encoded', @@ -41,8 +40,13 @@ use bsta_lib ( 'fail_method', 'fail_content_type', 'redirect', 'get_remote_addr', 'get_frame', 'get_password', 'merge_settings', - 'print_viewer_page', 'write_index', 'write_static_goto', - 'ong' + '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 = / @@ -50,14 +54,7 @@ use bsta_lib ( ###PERL_CGI_PATH: CGI_PATH = /bsta/ ###PERL_CGI_VIEWER_PATH: CGI_VIEWER_PATH = /bsta/v -###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta/ -###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/ @@ -83,7 +80,6 @@ my %words_data; my $method; my $frame; -my $frame_data_path; my $prev_frame_data_path; my $next_frame_data_path; my $password; @@ -95,6 +91,7 @@ my $timer_unlocked; my $fh; my $show_command; my $ongtime; +my $goto; my $text_mode; my $words_page; my $words_data_path; @@ -130,12 +127,11 @@ $IP = get_remote_addr(); $frame = get_frame(\%cgi); $password = get_password(\%cgi); -%settings = read_data_file(DATA_SETTINGS_PATH()); -%default = read_data_file(DATA_DEFAULT_PATH()); +%settings = read_settings(); +%default = read_default(); if ($frame >= 0) { - $frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame); - %frame_data= read_data_file($frame_data_path); + %frame_data= read_frame_data($frame); } $password_ok = ($password eq $settings{'password'}); @@ -144,14 +140,13 @@ $password_ok = ($password eq $settings{'password'}); if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STATE_PATH())) { if (flock($fh, 2)) { - %state = read_data_file($fh); + %state = read_state($fh); if ($frame < 0) { $frame = int($state{'last'}) + $frame +1; if ($frame >= 0) { $force_redirect = 1; - $frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame); - %frame_data = read_data_file($frame_data_path); + %frame_data = read_frame_data($frame); } } @@ -178,18 +173,30 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STATE_PATH())) { elsif ($state{'ip3'} eq '') { $new_state{'ip3'} = $IP; $new_state{'state'} = STATE->{'ready'}; - write_static_goto(\%new_state, \%settings, ''); } 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_data_file($fh, \%new_state); + write_state($fh, \%new_state); } } elsif ( (int($state{'state'}) == STATE->{'inactive'}) && - ($frame == 1) + ($frame == 1) && + (!$password_ok) ) { # ready to activate? # NOTE: at this point frame 0 is already ONGed. @@ -197,8 +204,8 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STATE_PATH())) { my $ong_time = int($settings{'firstongtime'}); my $r; - %story = read_data_file(DATA_STORY_PATH()); - %goto_list = read_data_file(DATA_LIST_PATH()); + %story = read_story(); + %goto_list = read_goto(); if ( (int($story{'state'}) == INTF_STATE->{'>|'} ) && @@ -235,7 +242,7 @@ if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STATE_PATH())) { $r = write_static_goto(\%state, \%settings, \%goto_list); } if ($r) { - $r = write_data_file($fh, \%state); + $r = write_state($fh, \%state); } unless ($r) { # FAILED ONG! Story as if it was inactive! @@ -269,16 +276,7 @@ if ($access) { exit redirect($method, CGI_PATH(), HTTP_STATUS->{'see_other'}); } elsif ($frame < int($state{'last'})) { - my $page_file; - if ($frame_data{'page'} ne '') { - $page_file = $frame_data{'page'}; - } - else { - $page_file = sprintf( - $settings{'frame'}, - $frame, 'htm' - ); - } + my $page_file = get_page_file($frame, \%frame_data, \%settings); if (_x_encoded('-f', join_path(PATH_SEPARATOR(), WWW_PATH() , $page_file) )) { @@ -296,6 +294,7 @@ if ($access) { {'path' => $frame} ); unless ($no_cgi) { + delete $cgi{'f'}; # to avoid infinite loop $redirect_url = merge_url( {'path' => $redirect_url}, {'query' => \%cgi} @@ -305,20 +304,17 @@ if ($access) { } if ($frame > 0) { - $prev_frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame-1); - %prev_frame_data = read_data_file($prev_frame_data_path); + %prev_frame_data = read_frame_data($frame-1, \%default); } - $next_frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame+1); - %next_frame_data = read_data_file($next_frame_data_path); - - %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); + 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_data_file(DATA_NOACCESS_PATH()); - %frame_data = merge_settings(\%default, \%frame_data); + %frame_data = read_noaccess(\%default); } $timer = int($state{'nextong'}) - $time; @@ -349,14 +345,11 @@ if($text_mode > TEXT_MODE->{'words'}) { $text_mode = TEXT_MODE->{'normal'}; } $words_page = int($cgi{'i'}); +$goto = int($cgi{'g'}); -$words_data_path = join_path(PATH_SEPARATOR(), DATA_WORDS_PATH(), $frame); -%words_data = read_data_file( - $words_data_path, # file - '', # encoding - 0, # no header - ($text_mode != TEXT_MODE->{'words'}), # header only - 1, # as list +%words_data = read_words_list( + $frame, + ($text_mode != TEXT_MODE->{'words'}) ); if (!$access) { @@ -379,7 +372,8 @@ print_viewer_page ( 'static' => 0, 'show_command' => $show_command, 'text_mode' => $text_mode, - 'words_page' => $words_page + 'words_page' => $words_page, + 'goto' => $goto }, \%state, \%settings,