added thread and thread::share and modified code appropriately. fixed bug where res_error() didn't return with an error code

This commit is contained in:
jake 2023-11-05 15:49:28 -05:00
parent 3bcfa93553
commit 904bcb6f61

View file

@ -28,6 +28,8 @@ use Getopt::Long;
use Carp::Always; use Carp::Always;
use Smart::Comments; use Smart::Comments;
use File::Temp qw(tempfile); use File::Temp qw(tempfile);
use threads;
use threads::shared;
my $user; my $user;
my $pass; my $pass;
@ -78,7 +80,7 @@ or die("Error in command line arguments\n");
die $death_string if $death_string; die $death_string if $death_string;
} }
my %files; my %files :shared;
my $suppress_list_update = 0; my $suppress_list_update = 0;
# for neocities, it can only be dir or file # for neocities, it can only be dir or file
@ -164,25 +166,31 @@ sub update_known_files {
$type = $TYPE_FILE; $type = $TYPE_FILE;
$mode = 0644; $mode = 0644;
} }
$files{$dirs}{$filename} = {
$files{$dirs} //= &share({}); # mmm, tasty nested shared memory
$files{$dirs}{$filename} = shared_clone({
type => $type, type => $type,
mode => $mode, mode => $mode,
ctime => $times, ctime => $times,
size => $size, size => $size,
}; fn => undef,
});
} }
$files{'/'}{'.'} = { $files{'/'}{'.'} = shared_clone({
type => $TYPE_DIR, type => $TYPE_DIR,
mode => 0755, mode => 0755,
ctime => time(), ctime => time(),
size => 4096, size => 4096,
}; fn => undef,
$files{'/'}{'..'} = { });
$files{'/'}{'..'} = shared_clone({
type => $TYPE_DIR, type => $TYPE_DIR,
mode => 0755, mode => 0755,
ctime => time(), ctime => time(),
size => 4096, size => 4096,
}; fn => undef,
});
# ## %files # ## %files
} }
@ -233,9 +241,10 @@ sub e_open {
return -ENOENT() unless exists($files{$dirs}{$file}); return -ENOENT() unless exists($files{$dirs}{$file});
return -EISDIR() if $files{$dirs}{$file}{type} & 0040; return -EISDIR() if $files{$dirs}{$file}{type} & 0040;
my $fh = [ rand() ]; #my $fh = [ rand() ];
return (0, $fh); #return (0, $fh);
return 0;
} }
sub e_create { sub e_create {
@ -270,18 +279,21 @@ sub e_statfs { return 255, 1, 1, 1, 1, 2 }
sub e_write { sub e_write {
my ($dirs, $file) = get_path_and_file(shift); my ($dirs, $file) = get_path_and_file(shift);
my ($buf, $off, $fh) = @_; my ($buf, $off, $_fh) = @_;
## # e_write ## # e_write
## # $off ## # $off
## # $fh ## # $fh
return -ENOENT() unless exists($files{$dirs}{$file}); return -ENOENT() unless exists($files{$dirs}{$file});
if (! exists $files{$dirs}{$file}{fh}) {
($files{$dirs}{$file}{fh}, $files{$dirs}{$file}{fn}) = tempfile(); if (! $files{$dirs}{$file}{fn}) {
# filehandles CANNOT be shared between threads
(undef, $files{$dirs}{$file}{fn}) = tempfile();
} }
my $fh2 = $files{$dirs}{$file}{fh}; open my $fh, '>>', $files{$dirs}{$file}{fn};
$fh2->autoflush( 1 ); # perl doesnt 'print line' until it sees "\n" normally $fh->autoflush( 1 ); # perl doesnt 'print line' until it sees "\n" normally
seek $fh2, $off, 0; seek $fh, $off, 0 if $off;
print $fh2 $buf; print $fh $buf;
close $fh;
# my $res = write_to_neocities($dirs, $file, $buf); # my $res = write_to_neocities($dirs, $file, $buf);
return length $buf; return length $buf;
@ -290,15 +302,17 @@ sub e_write {
sub e_flush { sub e_flush {
my ($path, $_fh) = @_; my ($path, $_fh) = @_;
my ($dirs, $file) = get_path_and_file($path); my ($dirs, $file) = get_path_and_file($path);
if (exists $files{$dirs}{$file}{fh}) { if ($files{$dirs}{$file}{fn}) {
my $fn = $files{$dirs}{$file}{fn}; my $fn = $files{$dirs}{$file}{fn};
my $res = write_to_neocities($dirs, $file, $fn, 1); my $res = write_to_neocities($dirs, $file, $fn, 1);
close $files{$dirs}{$file}{fh};
delete $files{$dirs}{$file}{fh};
unlink $files{$dirs}{$file}{fn}; unlink $files{$dirs}{$file}{fn};
delete $files{$dirs}{$file}{fn}; delete $files{$dirs}{$file}{fn};
return res_errno($res, 0); return res_errno($res, 0);
} }
else {
# ?
return 0;
}
} }
sub e_not_implimented { return -ENOSYS; } sub e_not_implimented { return -ENOSYS; }
@ -462,7 +476,7 @@ sub res_errno {
my $body = from_json($res->body); my $body = from_json($res->body);
my %error_codes = ( my %error_codes = (
'invalid_file_type' => -124, ## -EMEDIUMTYPE -- meant to convey that user can't upload this kind of file 'invalid_file_type' => -124, ## -EMEDIUMTYPE -- meant to convey that user can't upload this kind of file
'missing_files' => -ENOENT, # when uploading, should work normally with mv 'missing_files' => -ENOENT, # when uploading and neocities thinks you've uploaded no files
'too_large' => -EFBIG, 'too_large' => -EFBIG,
'too_many_files' => -EMFILE, #-ENOSPC, 'too_many_files' => -EMFILE, #-ENOSPC,
'directory_exists' => -EEXIST, 'directory_exists' => -EEXIST,
@ -478,7 +492,8 @@ sub res_errno {
'email_not_validated' => -56, # EBADRQC # invaild requuest code ¯\_(ツ)_/¯ 'email_not_validated' => -56, # EBADRQC # invaild requuest code ¯\_(ツ)_/¯
'invalid_auth' => -EACCES, 'invalid_auth' => -EACCES,
'not_found' => -ENOSYS, # calls to /api/ that doesn't exist (not that user should get this error message) 'not_found' => -ENOSYS, # calls to /api/ that doesn't exist (not that user should get this error message)
) );
return $error_codes{ $body->{error_type} };
} }
else { else {
# some kind of error, maybe related to internet? # some kind of error, maybe related to internet?
@ -491,7 +506,6 @@ sub write_to_neocities {
my ($dirs, $file, $buffer, $is_buf_fn) = @_; my ($dirs, $file, $buffer, $is_buf_fn) = @_;
defined $is_buf_fn or $is_buf_fn = 0; defined $is_buf_fn or $is_buf_fn = 0;
my $ua = Mojo::UserAgent->new(); my $ua = Mojo::UserAgent->new();
my $asset; my $asset;
if (! $is_buf_fn) { if (! $is_buf_fn) {
@ -501,7 +515,6 @@ sub write_to_neocities {
$asset = Mojo::Asset::File->new(path => $buffer); $asset = Mojo::Asset::File->new(path => $buffer);
} }
my ($tx, $res); my ($tx, $res);
if ($pass) { if ($pass) {
$tx = $ua->post("https://$user:$pass\@neocities.org/api/upload" => $tx = $ua->post("https://$user:$pass\@neocities.org/api/upload" =>
@ -542,6 +555,6 @@ Fuse::main(
utime =>"main::e_not_implimented", utime =>"main::e_not_implimented",
chown =>"main::e_not_implimented", chown =>"main::e_not_implimented",
chmod =>"main::e_not_implimented", chmod =>"main::e_not_implimented",
threaded=>0, threaded=>1,
#debug=>1, debug=>0,
); );