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