]> bicyclesonthemoon.info Git - ott/bsta/blob - info.1.pl
move merge_settings to common library
[ott/bsta] / info.1.pl
1 ###RUN_PERL: #!/usr/bin/perl
2
3 # /bsta/i
4 # info.pl is generated from info.1.pl.
5 #
6 # The frame/story info interface
7 #
8 # Copyright (C) 2017, 2023, 2024  Balthasar SzczepaƄski
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU Affero General Public License as
12 # published by the Free Software Foundation, either version 3 of the
13 # License, or (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 # GNU Affero General Public License for more details.
19 #
20 # You should have received a copy of the GNU Affero General Public License
21 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23 use strict;
24 use utf8;
25 # use Encode::Locale ('decode_argv');
26 use Encode ('encode', 'decode');
27
28 ###PERL_LIB: use lib /botm/lib/bsta
29 use botm_common (
30         'HTTP_STATUS',
31         'fail_method', 'fail_content_type',
32         'http_header_status',
33         'read_header_env',
34         'write_data_file',
35         'url_query_decode',
36         'merge_settings'
37 );
38 use bsta_lib (
39         'STATE',
40         'get_password',
41         'get_page_file', 'get_frame_file',
42         'read_frame_data', 'read_default', 'read_noaccess',
43         'read_settings', 'read_default', 'read_state',
44         'read_words_list', 'read_words', 'read_attachment'
45 );
46
47 binmode STDIN,  ':encoding(UTF-8)';
48 binmode STDOUT, ':encoding(UTF-8)';
49 binmode STDERR, ':encoding(UTF-8)';
50 # decode_argv();
51
52 my $time = time();
53 srand ($time-$$);
54
55 my %http;
56 my %cgi;
57 my %info_data;
58 my %next_frame_data;
59 my %default;
60 my %settings;
61 my %state;
62
63 my $method;
64 my $frame = '';
65 my $attachment = '';
66 my $words = '';
67 my $password;
68 my $password_ok;
69 my $access;
70 my $show_command;
71 my $ongtime;
72 my $timer;
73 my $ong_state;
74 my $last_frame;
75
76 delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
77 ###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin;
78
79 if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) {
80         $method = $1;
81 }
82 else{
83         exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']);
84 }
85
86 %http = read_header_env(\%ENV);
87 %cgi = url_query_decode($ENV{'QUERY_STRING'});
88
89 if ($method eq 'POST') {
90         if ($http{'content-type'} eq 'application/x-www-form-urlencoded') {
91                 my %cgi_post = url_query_decode( <STDIN> );
92                 %cgi = merge_settings(\%cgi, \%cgi_post);
93         }
94         # multipart not supported
95         else{
96                 exit fail_content_type($method, $http{'content-type'});
97         }
98 }
99
100 if ($cgi{'f'} =~ /^.+$/) {
101         $frame = int($&);
102 }
103 elsif ($cgi{'a'} =~ /^.+$/) {
104         $attachment = int($&);
105 }
106 elsif ($cgi{'i'} =~ /^.+$/) {
107         $attachment = int($&);
108 }
109 elsif ($cgi{'w'} =~ /^.+$/) {
110         $words = $&;
111 }
112 elsif ($ENV{'PATH_INFO'} =~ /^\/a\/?(.+)$/) {
113         $attachment = int($1);
114 }
115 elsif ($ENV{'PATH_INFO'} =~ /^\/w\/?(.+)$/) {
116         $words = $1;
117 }
118 elsif ($ENV{'PATH_INFO'} =~ /^\/(f\/?)?(.+)$/) {
119         $frame = int($2);
120 }
121
122 $password = get_password(\%cgi);
123
124 %settings   = read_settings();
125 %default    = read_default();
126 %state      = read_state(());
127
128 $ong_state  = int($state{'state'});
129 $last_frame = int($state{'last'});
130
131 $password_ok = ($password eq $settings{'password'});
132
133 # comment info, not frame
134 if ($words ne '') {
135         if ($words =~ /^[0-9]+$/) {
136                 %info_data = read_words_list(
137                         int($&), # id
138                         0, # header only
139                         1 # not as list
140                 );
141                 $frame = int($&);
142                 if ($info_data{'posts'} eq '') {
143                         $info_data{'posts'} = 0;
144                 }
145         }
146         elsif ($words =~ /^[0-9]+\.[0-9\.]+$/) {
147                 %info_data = read_words($&);
148                 $frame = ($info_data{'frame'} ne '') ? int($info_data{'frame'}) : -1;
149                 unless ($password_ok) {
150                         delete($info_data{'password'});
151                         delete($info_data{'key'});
152                 }
153         }
154 }
155 # attachment info, not frame
156 elsif ($attachment ne '') {
157         %info_data = read_attachment($attachment);
158         $frame = ($info_data{'frame'} ne '') ? int($info_data{'frame'}) : -1;
159 }
160 # frame info
161 elsif ($frame ne '') {
162         if ($frame < 0) {
163                 $frame = $last_frame + $frame +1;
164         }
165         %info_data       = read_frame_data($frame, \%default);
166         %next_frame_data = read_frame_data($frame+1, \%default);
167         
168         $timer   = int($state{'nextong'}) - $time;
169         $ongtime = int($state{'ongtime'});
170         if($ongtime == 0) {
171                 $ongtime = int($settings{'ongtime'})
172         }
173         $show_command = ($timer < ($ongtime * 3600 / 3));
174 }
175 # state info, not frame
176 else {
177         unless ($password_ok) {
178                 # just show if IP was saved, not its value
179                 if ($state{'ip1'} ne '') {
180                         $state{'ip1'} = 1;
181                 }
182                 if ($state{'ip2'} ne '') {
183                         $state{'ip2'} = 1;
184                 }
185                 if ($state{'ip3'} ne '') {
186                         $state{'ip3'} = 1;
187                 }
188         }
189         print "Content-type: text/plain; charset=UTF-8\n\n";
190         if ($method eq 'HEAD') {
191                 exit;
192         }
193         write_data_file(
194                 \*STDOUT, \%state, '',
195                 0, 0, 0,
196                 '>>', 1
197         );
198         
199         exit;
200 }
201
202 if (
203         $password_ok || (
204                 ($ong_state >= STATE->{'waiting'}) &&
205                 ($frame <= $last_frame) &&
206                 ($frame >= 0)
207         )
208 ) {
209         $access = 1;
210         
211         if (
212                 ($words eq '') &&
213                 ($attachment eq '') &&
214                 ($info_data{'command'} eq '') && (
215                         $password_ok ||
216                         ($frame < $last_frame) || (
217                                 ($ong_state >= STATE->{'ready'}) &&
218                                 $show_command
219                         )
220                 )
221         ) {
222                 $info_data{'command'} = $next_frame_data{'title'};
223         }
224 }
225 else {
226         $access = 0;
227         if (($attachment ne '') || ($words ne '')) {
228                 %info_data = ();
229         }
230         else {
231                 %info_data = read_noaccess(\%default);
232         }
233 }
234 if (
235         ($attachment eq '') &&
236         ($words eq '')
237 ) {
238         if ($info_data{'frame'} eq '') {
239                 $info_data{'frame'} = get_frame_file($frame, \%info_data, \%settings)
240         }
241         if ($info_data{'page'} eq '') {
242                 unless (($access) && ($frame < $last_frame)) {
243                         $info_data{'page'} = '';
244                 }
245                 else {
246                         $info_data{'page'} = get_page_file($frame, \%info_data, \%settings);
247                 }
248         }
249 }
250
251 print "Content-type: text/plain; charset=UTF-8\n";
252 if (!$access) {
253         print http_header_status(HTTP_STATUS->{'forbidden'});
254 }
255 print "\n";
256 if($method eq 'HEAD') {
257         exit;
258 }
259 write_data_file(
260         \*STDOUT, \%info_data, '',
261         0, 0, 0,
262         '>>', 1
263 );