]> bicyclesonthemoon.info Git - ott/bsta/blob - attach.1.pl
viewer redirects to static page; info includes static page;
[ott/bsta] / attach.1.pl
1 ###RUN_PERL: #!/usr/bin/perl
2
3 # /bsta/a
4 # attach.pl is generated from attach.1.pl.
5 #
6 # The attachment interface
7 #
8 # Copyright (C) 2016, 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         'read_header_env',
32         'url_query_decode',
33         'read_data_file',
34         'join_path',
35         'merge_url',
36         'open_encoded', 'stat_encoded',
37         'http_header_line', 'http_header_content_length', 'http_header_content_disposition'
38 );
39 use bsta_lib (
40         'STATE',
41         'merge_settings',
42         'get_id', 'get_password',
43         'fail_method', 'fail_content_type', 'fail_attachment', 'fail_500',
44         'redirect'
45 );
46
47 ###PERL_PATH_SEPARATOR:     PATH_SEPARATOR     = /
48
49 ###PERL_CGI_PATH:           CGI_PATH           = /bsta/
50
51 ###PERL_DATA_PATH:          DATA_PATH          = /botm/data/bsta
52 ###PERL_DATA_ATTACH_PATH:   DATA_ATTACH_PATH   = /botm/data/bsta/a
53 ###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings
54 ###PERL_DATA_STATE_PATH:    DATA_STATE_PATH    = /botm/data/bsta/state
55
56 ###PERL_WWW_PATH:           WWW_PATH           = /botm/www/1190/bsta/
57
58 binmode STDIN,  ':encoding(UTF-8)';
59 binmode STDOUT, ':encoding(UTF-8)';
60 binmode STDERR, ':encoding(UTF-8)';
61 # decode_argv();
62
63 my $time = time();
64 srand ($time-$$);
65
66 my %http;
67 my %cgi;
68 my %settings;
69 my %state;
70 my %file_data;
71
72 my $method;
73 my $ID;
74 my $frame;
75 my $last_frame;
76 my $ong_state;
77 my $password;
78 my $password_ok;
79 my $IP;
80 my $try_onged;
81 my $buffer;
82 my $fh;
83 my $file_path;
84 my $file_name;
85 my $direct;
86 my $r = 0;
87
88 delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
89 ###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin;
90
91 if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) {
92         $method = $1;
93 }
94 else{
95         exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']);
96 }
97
98 %http = read_header_env(\%ENV);
99 %cgi = url_query_decode($ENV{'QUERY_STRING'});
100
101 if ($method eq 'POST') {
102         if ($http{'content-type'} eq 'application/x-www-form-urlencoded') {
103                 my %cgi_post = url_query_decode( <STDIN> );
104                 %cgi = merge_settings(\%cgi, \%cgi_post);
105         }
106         # multipart not supported
107         else{
108                 exit fail_content_type($method, $http{'content-type'});
109         }
110 }
111
112 $ID       = get_id(      \%cgi);
113 $password = get_password(\%cgi);
114
115 %settings  = read_data_file(DATA_SETTINGS_PATH());
116 %state     = read_data_file(DATA_STATE_PATH());
117 %file_data = read_data_file(DATA_ATTACH_PATH().$ID);
118 $frame = ($file_data{'frame'} ne '') ? int($file_data{'frame'}) : -1;
119 $last_frame = int($state{'last'});
120 $ong_state  = int($state{'state'});
121 $file_name  = $file_data{'filename'};
122
123 $password_ok = ($password eq $settings{'password'});
124
125 unless (
126         ($file_name ne '') && (
127                 $password_ok || (
128                         ($ong_state >= STATE->{'waiting'}) &&
129                         ($frame <= $last_frame) &&
130                         ($frame >=0)
131                 )
132         )
133 ) {
134         exit fail_attachment($method, $ID);
135 }
136
137 if ($file_data{'content'} ne '') {
138         $direct = 1;
139 }
140 else {
141         $direct = 0;
142         $try_onged = (
143                 ($ong_state >= STATE->{'waiting'}) &&
144                 ($frame <= $last_frame) &&
145                 ($frame >=0)
146         );
147         if ($try_onged) {
148                 $file_path = join_path(PATH_SEPARATOR(), WWW_PATH(), $file_name);
149                 $r = open_encoded($fh, '<' , $file_path);
150                 if ($r) {
151                         close($r);
152                         $file_path = merge_url(
153                                 {'path' => CGI_PATH()},
154                                 {'path' => $file_name}
155                         );
156                         exit redirect ($method, $file_path, HTTP_STATUS->{'see_other'});
157                 }
158         }
159         unless ($r) {
160                 $file_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $file_name);
161                 $r = open_encoded($fh,'<', $file_path);
162                 unless ($r) {
163                         exit fail_attachment($method, $ID);
164                 }
165         }
166         unless (binmode($fh)) {
167                 close($fh);
168                 exit fail_500("Can't switch file to binary mode.");
169         }
170         if (my @file_info = stat_encoded($file_path)) {
171                 print http_header_content_length($file_info[7]);
172         }
173 }
174 if ($file_data{'content-type'} ne '') {
175         print http_header_line('content-type', $file_data{'content-type'});
176 }
177 if ($file_name ne '') {
178         print http_header_content_disposition('inline', $file_name);
179 }
180 unless ($direct) {
181         unless (binmode STDOUT) {
182                 close($fh);
183                 exit fail_500("Can't switch output to binary mode.");
184         }
185 }
186 print "\n";
187
188 if($method ne 'HEAD'){
189         if($direct) {
190                 print $file_data{'content'};
191         }
192         else {
193                 while (read ($fh, $buffer, 1024)) {
194                         print (STDOUT $buffer);
195                 }
196         }
197 }
198 unless ($direct) {
199         close($fh);
200 }