package main;
use strict;
use Plan9; # ./Plan9.pm
use Data::Dumper;
use Config;
use warnings;
use constant {
Qtop => 0,
Qtest => 1,
Qconfig => 2,
Qdate => 3,
};
my $testname = 'test'; # rename allowed
my $teststr = "test passed\n"; # write allowed
my $testvers = 0; # write counter
sub fsattach {
my ($r) = @_;
my $qid;
$qid = {
path=>Qtop,
vers=>0,
type=>Plan9::QTDIR,
};
$r->{fid}->{qid} = $qid;
$r->{ofcall}->{qid} = $qid;
Plan9::respond($r);
}
sub fswalk {
my ($r) = @_;
my ($path, @wqid, $fntab, $fn);
$path = $r->{fid}->{qid}->{path};
$fntab = {
&Qtop => {
$testname => sub {
$path = Qtest;
push(@wqid, {path=>$path, vers=>$testvers, type=>0});
},
'config' => sub {
$path = Qconfig;
push(@wqid, {path=>$path, vers=>0, type=>0});
},
'date' => sub {
$path = Qdate;
push(@wqid, {path=>$path, vers=>0, type=>0});
},
},
};
for(@{$r->{ifcall}->{wname}}){
if($_ eq '..'){
$path = Qtop;
push(@wqid, {path=>$path, vers=>0, type=>Plan9::QTDIR});
next;
}
$fn = $fntab->{$path}->{$_};
if(!defined $fn or !&$fn()){
last;
}
}
$r->{ofcall}->{wqid} = \@wqid;
Plan9::respond($r);
}
sub getstat {
my ($path) = @_;
my ($d, $fntab);
$d = {};
%{$d} = %Plan9::nulldir;
$d->{qid} = {path=>$path, vers=>0, type=>0};
$d->{uid} = $d->{gid} = $d->{muid} = "tester";
$d->{mode} = 0444;
$fntab = {
&Qtop => sub {
$d->{name} = ".";
$d->{qid}->{type} = Plan9::QTDIR;
},
&Qtest => sub {
$d->{name} = $testname;
$d->{qid}->{vers} = $testvers;
$d->{mode} = 0666;
$d->{length} = length($teststr);
},
&Qconfig => sub {
$d->{name} = "config";
},
&Qdate => sub {
$d->{name} = "date";
},
};
&{$fntab->{$path}}();
if($d->{qid}->{type}&Plan9::QTDIR){
$d->{mode} |= 0111 | Plan9::DMDIR;
}
return $d;
}
sub fsstat {
my ($r) = @_;
$r->{d} = getstat($r->{fid}->{qid}->{path});
Plan9::respond($r);
}
sub fswstat {
my ($r) = @_;
my $path;
$path = $r->{fid}->{qid}->{path};
if($path != Qtest
or $r->{d}->{mode} != $Plan9::syncdir{mode}
or $r->{d}->{uid} ne $Plan9::syncdir{uid}
or $r->{d}->{gid} ne $Plan9::syncdir{gid}){
Plan9::respond($r, "permission denied");
return;
}
if($r->{d}->{name} ne $Plan9::syncdir{name}){
$testname = $r->{d}->{name};
}
if($r->{d}->{length} != $Plan9::syncdir{length}){
$teststr = substr($teststr, 0, $r->{d}->{length});
}
Plan9::respond($r);
}
sub fsread {
my ($r) = @_;
my ($path, $gen);
$path = $r->{fid}->{qid}->{path};
if($path == Qtop){
$gen = sub {
return undef unless exists $_[$_];
return getstat($_[$_]);
};
Plan9::dirread9p($r, $gen, Qtest, Qconfig, Qdate);
Plan9::respond($r);
}elsif($path == Qtest){
Plan9::readstr($r, $teststr);
Plan9::respond($r);
}elsif($path == Qconfig){
Plan9::readstr($r, Config::myconfig());
Plan9::respond($r);
}elsif($path == Qdate){
Plan9::readstr($r, `date`);
Plan9::respond($r);
}else{
Plan9::respond($r, "programming error in fsread");
}
}
sub fswrite {
my ($r) = @_;
my ($path, $gen);
$path = $r->{fid}->{qid}->{path};
if($path != Qtest){
Plan9::respond($r, "permission denied");
return;
}
$teststr = $r->{ifcall}->{data}; # offset ignored
++$testvers;
$r->{ofcall}->{count} = length($r->{ifcall}->{data});
Plan9::respond($r);
}
my $srv = {
ior => \*STDIN,
iow => \*STDOUT,
attach => \&fsattach,
walk => \&fswalk,
read => \&fsread,
write => \&fswrite,
stat => \&fsstat,
wstat => \&fswstat,
};
$::chatty9p = 1;
Plan9::srv($srv);
# rm -f /srv/p; srv -e 'Perl $%' p /n/local
|