From a1abc8b294a2d062fccc1849320a14055cbc54b7 Mon Sep 17 00:00:00 2001 From: b Date: Tue, 2 Jan 2024 13:12:20 +0000 Subject: [PATCH] info supports attachments --- bsta_lib.1.pm | 2 +- info.1.pl | 236 +++++++++++++++++++++++++++++--------------------- ong.1.pl | 5 ++ viewer.1.pl | 2 + 4 files changed, 147 insertions(+), 98 deletions(-) diff --git a/bsta_lib.1.pm b/bsta_lib.1.pm index 6d90ed8..27df76b 100644 --- a/bsta_lib.1.pm +++ b/bsta_lib.1.pm @@ -378,7 +378,7 @@ sub get_id { return int($1); } else { - return int($default); + return $default; } } diff --git a/info.1.pl b/info.1.pl index 8772005..c1eeda5 100644 --- a/info.1.pl +++ b/info.1.pl @@ -5,7 +5,7 @@ # # The frame/story info interface # -# Copyright (C) 2017, 2023 Balthasar Szczepański +# 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 @@ -21,160 +21,202 @@ # along with this program. If not, see . use strict; -#use warnings; +use utf8; +# use Encode::Locale ('decode_argv'); +use Encode ('encode', 'decode'); + ###PERL_LIB: use lib /botm/lib/bsta -use bsta_lib qw(failpage gethttpheader getcgi readdatafile printdatafile); -use File::Copy; +use botm_common ( + 'read_header_env', + 'read_data_file', 'write_data_file', + 'url_query_decode', + 'join_path' +); +use bsta_lib ( + 'STATE', + 'fail_method', 'fail_content_type', + 'get_password', + 'merge_settings' +); + +###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 +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 %framedata; -my %nextframedata; +my %frame_data; +my %next_frame_data; my %default; my %settings; my %state; -my $time = time(); -srand ($time-$$); - my $method; -my $frame; +my $frame = ''; +my $attachment = ''; my $password; -my $passwordOK; +my $password_ok; my $access; -my $showcommand; +my $show_command; my $ongtime; -my $seconds; +my $timer; +my $frame_data_path; +my $next_frame_data_path; +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; + $method = $1; } else{ - exit failpage("Status: 405 Method Not Allowed\nAllow: GET, POST, HEAD\n","405 Method Not Allowed","The interface does not support the $ENV{'REQUEST_METHOD'} method.",$method); + exit fail_method($ENV{'REQUEST_METHOD'}, 'GET, POST, HEAD'); } -%http = gethttpheader (\%ENV); -%cgi = getcgi($ENV{'QUERY_STRING'}); +%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 %cgipost=getcgi( ); - foreach my $ind (keys %cgipost) { - $cgi{$ind}=$cgipost{$ind}; - } + my %cgi_post = url_query_decode( ); + %cgi = merge_settings(\%cgi, \%cgi_post); } # multipart not supported else{ - exit failpage("Status: 415 Unsupported Media Type\n","415 Unsupported Media Type","Unsupported Content-type: $http{'content-type'}."); + exit fail_content_type($method, $http{'content-type'}); } } -if ($cgi{'f'} =~ /^(.+)$/) { - $frame=int($1); -} -elsif ($ENV{'PATH_INFO'} =~ /^\/(.+)$/) { - $frame=int($1); +if ($cgi{'f'} =~ /^.+$/) { + $frame = int($&); } -else { - $frame = ''; +elsif ($cgi{'i'} =~ /^.+$/) { + $attachment = int($&); } - -if ($cgi{'p'} =~ /^(.+)$/) { - $password=$1; +elsif ($ENV{'PATH_INFO'} =~ /^\/a(.+)$/) { + $attachment = int($1); } -else { - $password=''; +elsif ($ENV{'PATH_INFO'} =~ /^\/(.+)$/) { + $frame = int($1); } -%settings=readdatafile(DATA_SETTINGS_PATH); -%default=readdatafile(DATA_DEFAULT_PATH); -%framedata=readdatafile(DATA_PATH.$frame); -%state=readdatafile(DATA_STATE_PATH); -if($password eq $settings{'password'}){ - $passwordOK = 1; +$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()); + +$ong_state = int($state{'state'}); +$last_frame = int($state{'last'}); + +$password_ok = ($password eq $settings{'password'}); + +# attachment info, not frame +if ($attachment ne '') { + %frame_data = read_data_file(DATA_ATTACH_PATH().$attachment); + $frame = ($frame_data{'frame'} ne '') ? int($frame_data{'frame'}) : -1; } -else{ - $passwordOK = 0; +# frame info +elsif ($frame ne '') { + if ($frame < 0) { + $frame = $last_frame + $frame +1; + } + $frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame); + $next_frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame+1); + %frame_data = read_data_file($frame_data_path); + %next_frame_data = read_data_file($next_frame_data_path); + %frame_data = merge_settings(\%default, \%frame_data); + %next_frame_data = merge_settings(\%default, \%next_frame_data); + + $timer = int($state{'nextong'}) - $time; + $ongtime = int($state{'ongtime'}); + if($ongtime == 0) { + $ongtime = int($settings{'ongtime'}) + } + $show_command = ($timer < ($ongtime * 3600 / 3)); } - -if ($frame eq '') { - unless($passwordOK) { +# state info, not frame +else { + unless ($password_ok) { + # just show if IP was saved, not its value if ($state{'ip1'} ne '') { - $state{'ip1'}=1; + $state{'ip1'} = 1; } if ($state{'ip2'} ne '') { - $state{'ip2'}=1; + $state{'ip2'} = 1; } if ($state{'ip3'} ne '') { - $state{'ip3'}=1; + $state{'ip3'} = 1; } } print "Content-type: text/plain\n\n"; - if($method eq 'HEAD') { + if ($method eq 'HEAD') { exit; } - printdatafile(%state); + write_data_file(\*STDOUT, '', '', \%state); + exit; } -else { - if($frame<0) { - $frame = int($state{'last'}) + $frame +1; - %framedata=readdatafile(DATA_PATH.$frame); - } - - %nextframedata=readdatafile(DATA_PATH.($frame+1)); +if ( + $password_ok || ( + ($ong_state >= STATE->{'waiting'}) && + ($frame <= $last_frame) && + ($frame >= 0) + ) +) { + $access = 1; - foreach my $ind (keys %default) { - unless(defined($framedata{$ind})){ - $framedata{$ind}=$default{$ind}; - } - unless(defined($nextframedata{$ind})){ - $nextframedata{$ind}=$default{$ind}; - } - } - $seconds=int($state{'nextong'})-$time; - $ongtime=int($state{'ongtime'}); - if($ongtime == 0) { - $ongtime=int($settings{'ongtime'}) + if ( + ($attachment eq '') && + ($frame_data{'command'} eq '') && ( + $password_ok || + ($frame < $last_frame) || ( + ($ong_state >= STATE->{'ready'}) && + $show_command + ) + ) + ) { + $frame_data{'command'} = $next_frame_data{'title'}; } - $showcommand = ($seconds < ($ongtime*3600/3)); - - if ($passwordOK || (int($state{'state'}) >= 1 && $frame <= int($state{'last'}) && $frame >= 0)) { - $access=1; - - if ($passwordOK || $frame= 2 && $showcommand)) { - $framedata{'command'}=$nextframedata{'title'}; - } - $framedata{'frame'}=sprintf($settings{'frame'},$frame,$framedata{'ext'}); +} +else { + $access = 0; + if ($attachment ne '') { + %frame_data = (); } else { - $access=0; - %framedata = readdatafile(DATA_NOACCESS_PATH); - foreach my $ind (keys %default) { - unless(defined($framedata{$ind})){ - $framedata{$ind}=$default{$ind}; - } - } - } - - # $framedata{'frame'}=sprintf($settings{'frame'},$frame,$framedata{'ext'}); - - print "Content-type: text/plain\n"; - if(!$access) { - print "Status: 403 Forbidden\n"; + %frame_data = read_data_file(DATA_NOACCESS_PATH()); + %frame_data = merge_settings(\%default, \%frame_data); } - print "\n"; - if($method eq 'HEAD') { - exit; - } - printdatafile(%framedata); } +if ( + ($frame_data{'frame'} eq '') && + ($attachment eq '') +) { + $frame_data{'frame'} = sprintf($settings{'frame'}, $frame, $frame_data{'ext'}); +} + +print "Content-type: text/plain\n"; +if (!$access) { + print "Status: 403 Forbidden\n"; +} +print "\n"; +if($method eq 'HEAD') { + exit; +} +write_data_file(\*STDOUT, '', '', \%frame_data); diff --git a/ong.1.pl b/ong.1.pl index ef90632..cea6a13 100644 --- a/ong.1.pl +++ b/ong.1.pl @@ -36,6 +36,11 @@ use bsta_lib ( ###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)'; +binmode STDOUT, ':encoding(UTF-8)'; +binmode STDERR, ':encoding(UTF-8)'; +# decode_argv(); + my $time = time(); srand ($time-$$); diff --git a/viewer.1.pl b/viewer.1.pl index 263e502..94bc529 100644 --- a/viewer.1.pl +++ b/viewer.1.pl @@ -95,6 +95,7 @@ else{ %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( ); @@ -105,6 +106,7 @@ if ($method eq 'POST') { exit fail_content_type($method, $http{'content-type'}); } } + $IP = get_remote_addr(); $frame = get_frame(\%cgi); $password = get_password(\%cgi); -- 2.30.2