mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-26 07:28:20 +08:00
new files and directories appear to work properly
This commit is contained in:
@ -2,7 +2,6 @@ package ipns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -126,7 +125,7 @@ func (*Root) Attr() fuse.Attr {
|
|||||||
|
|
||||||
// Lookup performs a lookup under this node.
|
// Lookup performs a lookup under this node.
|
||||||
func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
|
func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
|
||||||
log.Debug("ipns: Root Lookup: '%s' [intr = %s]", name, intr.String())
|
log.Debug("ipns: Root Lookup: '%s'", name)
|
||||||
switch name {
|
switch name {
|
||||||
case "mach_kernel", ".hidden", "._.":
|
case "mach_kernel", ".hidden", "._.":
|
||||||
// Just quiet some log noise on OS X.
|
// Just quiet some log noise on OS X.
|
||||||
@ -183,7 +182,9 @@ func (r *Root) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) {
|
|||||||
// Node is the core object representing a filesystem tree node.
|
// Node is the core object representing a filesystem tree node.
|
||||||
type Node struct {
|
type Node struct {
|
||||||
nsRoot *Node
|
nsRoot *Node
|
||||||
name string
|
|
||||||
|
// Name really only for logging purposes
|
||||||
|
name string
|
||||||
|
|
||||||
// Private keys held by nodes at the root of a keyspace
|
// Private keys held by nodes at the root of a keyspace
|
||||||
key ci.PrivKey
|
key ci.PrivKey
|
||||||
@ -205,16 +206,13 @@ func (s *Node) loadData() error {
|
|||||||
|
|
||||||
// Attr returns the attributes of a given node.
|
// Attr returns the attributes of a given node.
|
||||||
func (s *Node) Attr() fuse.Attr {
|
func (s *Node) Attr() fuse.Attr {
|
||||||
u.DOut("Node attr.\n")
|
|
||||||
if s.cached == nil {
|
if s.cached == nil {
|
||||||
s.loadData()
|
s.loadData()
|
||||||
}
|
}
|
||||||
switch s.cached.GetType() {
|
switch s.cached.GetType() {
|
||||||
case mdag.PBData_Directory:
|
case mdag.PBData_Directory:
|
||||||
u.DOut("this is a directory.\n")
|
|
||||||
return fuse.Attr{Mode: os.ModeDir | 0555}
|
return fuse.Attr{Mode: os.ModeDir | 0555}
|
||||||
case mdag.PBData_File, mdag.PBData_Raw:
|
case mdag.PBData_File, mdag.PBData_Raw:
|
||||||
u.DOut("this is a file.\n")
|
|
||||||
size, _ := s.Nd.Size()
|
size, _ := s.Nd.Size()
|
||||||
return fuse.Attr{
|
return fuse.Attr{
|
||||||
Mode: 0666,
|
Mode: 0666,
|
||||||
@ -222,14 +220,14 @@ func (s *Node) Attr() fuse.Attr {
|
|||||||
Blocks: uint64(len(s.Nd.Links)),
|
Blocks: uint64(len(s.Nd.Links)),
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
u.PErr("Invalid data type.")
|
log.Error("Invalid data type.")
|
||||||
return fuse.Attr{}
|
return fuse.Attr{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup performs a lookup under this node.
|
// Lookup performs a lookup under this node.
|
||||||
func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
|
func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
|
||||||
log.Debug("ipns: node[%s] Lookup '%s' [intr= %s]", s.name, name, intr.String())
|
log.Debug("ipns: node[%s] Lookup '%s'", s.name, name)
|
||||||
nd, err := s.Ipfs.Resolver.ResolveLinks(s.Nd, []string{name})
|
nd, err := s.Ipfs.Resolver.ResolveLinks(s.Nd, []string{name})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// todo: make this error more versatile.
|
// todo: make this error more versatile.
|
||||||
@ -243,7 +241,7 @@ func (n *Node) makeChild(name string, node *mdag.Node) *Node {
|
|||||||
child := &Node{
|
child := &Node{
|
||||||
Ipfs: n.Ipfs,
|
Ipfs: n.Ipfs,
|
||||||
Nd: node,
|
Nd: node,
|
||||||
name: name,
|
name: n.name + "/" + name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.nsRoot == nil {
|
if n.nsRoot == nil {
|
||||||
@ -286,10 +284,10 @@ func (s *Node) ReadAll(intr fs.Intr) ([]byte, fuse.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error {
|
func (n *Node) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error {
|
||||||
|
log.Debug("ipns: Node Write: flags = %s, offset = %d, size = %d", req.Flags.String(), req.Offset, len(req.Data))
|
||||||
if n.dataBuf == nil {
|
if n.dataBuf == nil {
|
||||||
n.dataBuf = new(bytes.Buffer)
|
n.dataBuf = new(bytes.Buffer)
|
||||||
}
|
}
|
||||||
log.Debug("ipns: Node Write: flags = %s, offset = %d, size = %d", req.Flags.String(), req.Offset, len(req.Data))
|
|
||||||
if req.Offset == 0 {
|
if req.Offset == 0 {
|
||||||
n.dataBuf.Reset()
|
n.dataBuf.Reset()
|
||||||
n.dataBuf.Write(req.Data)
|
n.dataBuf.Write(req.Data)
|
||||||
@ -316,46 +314,51 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error {
|
|||||||
return fuse.ENODATA
|
return fuse.ENODATA
|
||||||
}
|
}
|
||||||
|
|
||||||
read, err := mdag.NewDagReader(n.Nd, n.Ipfs.DAG)
|
err = n.updateTree()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
log.Error("updateTree failed: %s", err)
|
||||||
}
|
|
||||||
|
|
||||||
io.Copy(os.Stdout, read)
|
|
||||||
|
|
||||||
var root *Node
|
|
||||||
if n.nsRoot != nil {
|
|
||||||
root = n.nsRoot
|
|
||||||
} else {
|
|
||||||
root = n
|
|
||||||
}
|
|
||||||
|
|
||||||
err = root.Nd.Update()
|
|
||||||
if err != nil {
|
|
||||||
log.Error("ipns: dag tree update failed: %s", err)
|
|
||||||
return fuse.ENODATA
|
return fuse.ENODATA
|
||||||
}
|
}
|
||||||
|
|
||||||
err = n.Ipfs.DAG.AddRecursive(root.Nd)
|
}
|
||||||
if err != nil {
|
return nil
|
||||||
log.Critical("ipns: Dag Add Error: %s", err)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
n.changed = false
|
func (n *Node) updateTree() error {
|
||||||
n.dataBuf = nil
|
var root *Node
|
||||||
|
if n.nsRoot != nil {
|
||||||
|
root = n.nsRoot
|
||||||
|
} else {
|
||||||
|
root = n
|
||||||
|
}
|
||||||
|
|
||||||
ndkey, err := root.Nd.Key()
|
err := root.Nd.Update()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("getKey error: %s", err)
|
log.Error("ipns: dag tree update failed: %s", err)
|
||||||
// return fuse.ETHISREALLYSUCKS
|
return err
|
||||||
return fuse.ENODATA
|
}
|
||||||
}
|
|
||||||
log.Debug("Publishing changes!")
|
|
||||||
|
|
||||||
err = n.Ipfs.Publisher.Publish(root.key, ndkey.Pretty())
|
err = n.Ipfs.DAG.AddRecursive(root.Nd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("ipns: Publish Failed: %s", err)
|
log.Critical("ipns: Dag Add Error: %s", err)
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
n.changed = false
|
||||||
|
n.dataBuf = nil
|
||||||
|
|
||||||
|
ndkey, err := root.Nd.Key()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("getKey error: %s", err)
|
||||||
|
// return fuse.ETHISREALLYSUCKS
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debug("Publishing changes!")
|
||||||
|
|
||||||
|
err = n.Ipfs.Publisher.Publish(root.key, ndkey.Pretty())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("ipns: Publish Failed: %s", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -383,6 +386,8 @@ func (n *Node) Mkdir(req *fuse.MkdirRequest, intr fs.Intr) (fs.Node, fuse.Error)
|
|||||||
child.nsRoot = n.nsRoot
|
child.nsRoot = n.nsRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n.updateTree()
|
||||||
|
|
||||||
return child, nil
|
return child, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,13 +395,15 @@ func (n *Node) Mknod(req *fuse.MknodRequest, intr fs.Intr) (fs.Node, fuse.Error)
|
|||||||
log.Debug("Got mknod request!")
|
log.Debug("Got mknod request!")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) {
|
func (n *Node) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) {
|
||||||
log.Debug("[%s] Received open request! flags = %s", n.name, req.Flags.String())
|
log.Debug("[%s] Received open request! flags = %s", n.name, req.Flags.String())
|
||||||
|
//TODO: check open flags and truncate if necessary
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr fs.Intr) (fs.Node, fs.Handle, fuse.Error) {
|
func (n *Node) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr fs.Intr) (fs.Node, fs.Handle, fuse.Error) {
|
||||||
log.Debug("Got create request!")
|
log.Debug("Got create request: %s", req.Name)
|
||||||
nd := new(mdag.Node)
|
nd := new(mdag.Node)
|
||||||
nd.Data = mdag.FilePBData(nil)
|
nd.Data = mdag.FilePBData(nil)
|
||||||
child := n.makeChild(req.Name, nd)
|
child := n.makeChild(req.Name, nd)
|
||||||
@ -406,12 +413,45 @@ func (n *Node) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr f
|
|||||||
log.Error("Error adding child to node: %s", err)
|
log.Error("Error adding child to node: %s", err)
|
||||||
return nil, nil, fuse.ENOENT
|
return nil, nil, fuse.ENOENT
|
||||||
}
|
}
|
||||||
return child, nil, nil
|
return child, child, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Remove(req *fuse.RemoveRequest, intr fs.Intr) fuse.Error {
|
func (n *Node) Remove(req *fuse.RemoveRequest, intr fs.Intr) fuse.Error {
|
||||||
log.Debug("Got Remove request!")
|
log.Debug("[%s] Got Remove request: %s", n.name, req.Name)
|
||||||
return fuse.EIO
|
err := n.Nd.RemoveNodeLink(req.Name)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Remove: No such file.")
|
||||||
|
return fuse.ENOENT
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Rename(req *fuse.RenameRequest, newDir fs.Node, intr fs.Intr) fuse.Error {
|
||||||
|
log.Debug("Got Rename request '%s' -> '%s'", req.OldName, req.NewName)
|
||||||
|
var mdn *mdag.Node
|
||||||
|
for _, l := range n.Nd.Links {
|
||||||
|
if l.Name == req.OldName {
|
||||||
|
mdn = l.Node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if mdn == nil {
|
||||||
|
log.Critical("nil Link found on rename!")
|
||||||
|
return fuse.ENOENT
|
||||||
|
}
|
||||||
|
n.Nd.RemoveNodeLink(req.OldName)
|
||||||
|
|
||||||
|
switch newDir := newDir.(type) {
|
||||||
|
case *Node:
|
||||||
|
err := newDir.Nd.AddNodeLink(req.NewName, mdn)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Error adding node to new dir on rename: %s", err)
|
||||||
|
return fuse.ENOENT
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
log.Critical("Unknown node type for rename target dir!")
|
||||||
|
return fuse.ENOENT
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mount mounts an IpfsNode instance at a particular path. It
|
// Mount mounts an IpfsNode instance at a particular path. It
|
||||||
|
@ -65,6 +65,16 @@ func (n *Node) AddNodeLink(name string, that *Node) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Node) RemoveNodeLink(name string) error {
|
||||||
|
for i, l := range n.Links {
|
||||||
|
if l.Name == name {
|
||||||
|
n.Links = append(n.Links[:i], n.Links[i+1:]...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return u.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
// Size returns the total size of the data addressed by node,
|
// Size returns the total size of the data addressed by node,
|
||||||
// including the total sizes of references.
|
// including the total sizes of references.
|
||||||
func (n *Node) Size() (uint64, error) {
|
func (n *Node) Size() (uint64, error) {
|
||||||
|
@ -15,7 +15,7 @@ type DNSResolver struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *DNSResolver) Matches(name string) bool {
|
func (r *DNSResolver) Matches(name string) bool {
|
||||||
return strings.Contains(name, ".")
|
return strings.Contains(name, ".") && !strings.HasPrefix(name, ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TXT records for a given domain name should contain a b58
|
// TXT records for a given domain name should contain a b58
|
||||||
|
Reference in New Issue
Block a user