diff --git a/neocitiesfs.pl b/neocitiesfs.pl index c9c0225..e0e8b53 100755 --- a/neocitiesfs.pl +++ b/neocitiesfs.pl @@ -28,6 +28,8 @@ use Getopt::Long; use Carp::Always; use Smart::Comments; use File::Temp qw(tempfile); +use threads; +use threads::shared; my $user; my $pass; @@ -78,7 +80,7 @@ or die("Error in command line arguments\n"); die $death_string if $death_string; } -my %files; +my %files :shared; my $suppress_list_update = 0; # for neocities, it can only be dir or file @@ -164,25 +166,31 @@ sub update_known_files { $type = $TYPE_FILE; $mode = 0644; } - $files{$dirs}{$filename} = { + + $files{$dirs} //= &share({}); # mmm, tasty nested shared memory + + $files{$dirs}{$filename} = shared_clone({ type => $type, mode => $mode, ctime => $times, size => $size, - }; + fn => undef, + }); } - $files{'/'}{'.'} = { + $files{'/'}{'.'} = shared_clone({ type => $TYPE_DIR, mode => 0755, ctime => time(), size => 4096, - }; - $files{'/'}{'..'} = { + fn => undef, + }); + $files{'/'}{'..'} = shared_clone({ type => $TYPE_DIR, mode => 0755, ctime => time(), size => 4096, - }; + fn => undef, + }); # ## %files } @@ -233,9 +241,10 @@ sub e_open { return -ENOENT() unless exists($files{$dirs}{$file}); return -EISDIR() if $files{$dirs}{$file}{type} & 0040; - my $fh = [ rand() ]; - - return (0, $fh); + #my $fh = [ rand() ]; + + #return (0, $fh); + return 0; } sub e_create { @@ -270,18 +279,21 @@ sub e_statfs { return 255, 1, 1, 1, 1, 2 } sub e_write { my ($dirs, $file) = get_path_and_file(shift); - my ($buf, $off, $fh) = @_; + my ($buf, $off, $_fh) = @_; ## # e_write ## # $off ## # $fh 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}; - $fh2->autoflush( 1 ); # perl doesnt 'print line' until it sees "\n" normally - seek $fh2, $off, 0; - print $fh2 $buf; + open my $fh, '>>', $files{$dirs}{$file}{fn}; + $fh->autoflush( 1 ); # perl doesnt 'print line' until it sees "\n" normally + seek $fh, $off, 0 if $off; + print $fh $buf; + close $fh; # my $res = write_to_neocities($dirs, $file, $buf); return length $buf; @@ -290,15 +302,17 @@ sub e_write { sub e_flush { my ($path, $_fh) = @_; 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 $res = write_to_neocities($dirs, $file, $fn, 1); - close $files{$dirs}{$file}{fh}; - delete $files{$dirs}{$file}{fh}; unlink $files{$dirs}{$file}{fn}; delete $files{$dirs}{$file}{fn}; return res_errno($res, 0); } + else { + # ? + return 0; + } } sub e_not_implimented { return -ENOSYS; } @@ -462,7 +476,7 @@ sub res_errno { my $body = from_json($res->body); my %error_codes = ( '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_many_files' => -EMFILE, #-ENOSPC, 'directory_exists' => -EEXIST, @@ -478,7 +492,8 @@ sub res_errno { 'email_not_validated' => -56, # EBADRQC # invaild requuest code ¯\_(ツ)_/¯ 'invalid_auth' => -EACCES, '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 { # some kind of error, maybe related to internet? @@ -490,7 +505,6 @@ sub res_errno { sub write_to_neocities { my ($dirs, $file, $buffer, $is_buf_fn) = @_; defined $is_buf_fn or $is_buf_fn = 0; - my $ua = Mojo::UserAgent->new(); my $asset; @@ -501,7 +515,6 @@ sub write_to_neocities { $asset = Mojo::Asset::File->new(path => $buffer); } - my ($tx, $res); if ($pass) { $tx = $ua->post("https://$user:$pass\@neocities.org/api/upload" => @@ -542,6 +555,6 @@ Fuse::main( utime =>"main::e_not_implimented", chown =>"main::e_not_implimented", chmod =>"main::e_not_implimented", - threaded=>0, - #debug=>1, + threaded=>1, + debug=>0, );