예제 #1
0
파일: set.go 프로젝트: hernad/syncthing
func nativeFileIterator(fn Iterator) Iterator {
	return func(fi FileIntf) bool {
		switch f := fi.(type) {
		case protocol.FileInfo:
			f.Name = osutil.NativeFilename(f.Name)
			return fn(f)
		case FileInfoTruncated:
			f.Name = osutil.NativeFilename(f.Name)
			return fn(f)
		default:
			panic("unknown interface type")
		}
	}
}
예제 #2
0
func init() {
	defer func() {
		if err := recover(); err != nil {
			// Ensure that the supported flag is disabled when we hit an
			// error, even though it should already be. Also, silently swallow
			// the error since it's fine for a system not to support symlinks.
			Supported = false
		}
	}()

	// Needs administrator privileges.
	// Let's check that everything works.
	// This could be done more officially:
	// http://stackoverflow.com/questions/2094663/determine-if-windows-process-has-privilege-to-create-symbolic-link
	// But I don't want to define 10 more structs just to look this up.
	base := os.TempDir()
	path := filepath.Join(base, "symlinktest")
	defer os.Remove(path)

	err := Create(path, base, protocol.FlagDirectory)
	if err != nil {
		return
	}

	stat, err := osutil.Lstat(path)
	if err != nil || stat.Mode()&os.ModeSymlink == 0 {
		return
	}

	target, flags, err := Read(path)
	if err != nil || osutil.NativeFilename(target) != base || flags&protocol.FlagDirectory == 0 {
		return
	}
	Supported = true
}
예제 #3
0
파일: set.go 프로젝트: hernad/syncthing
func (s *FileSet) GetGlobalTruncated(file string) (FileInfoTruncated, bool) {
	fi, ok := s.db.getGlobal([]byte(s.folder), []byte(osutil.NormalizedFilename(file)), true)
	if !ok {
		return FileInfoTruncated{}, false
	}
	f := fi.(FileInfoTruncated)
	f.Name = osutil.NativeFilename(f.Name)
	return f, true
}
예제 #4
0
파일: set.go 프로젝트: hernad/syncthing
func (s *FileSet) GetGlobal(file string) (protocol.FileInfo, bool) {
	fi, ok := s.db.getGlobal([]byte(s.folder), []byte(osutil.NormalizedFilename(file)), false)
	if !ok {
		return protocol.FileInfo{}, false
	}
	f := fi.(protocol.FileInfo)
	f.Name = osutil.NativeFilename(f.Name)
	return f, true
}
예제 #5
0
// Iterate takes an iterator function which iterates over all matching blocks
// for the given hash. The iterator function has to return either true (if
// they are happy with the block) or false to continue iterating for whatever
// reason. The iterator finally returns the result, whether or not a
// satisfying block was eventually found.
func (f *BlockFinder) Iterate(folders []string, hash []byte, iterFn func(string, string, int32) bool) bool {
	var key []byte
	for _, folder := range folders {
		folderID := f.db.folderIdx.ID([]byte(folder))
		key = blockKeyInto(key, hash, folderID, "")
		iter := f.db.NewIterator(util.BytesPrefix(key), nil)
		defer iter.Release()

		for iter.Next() && iter.Error() == nil {
			file := blockKeyName(iter.Key())
			index := int32(binary.BigEndian.Uint32(iter.Value()))
			if iterFn(folder, osutil.NativeFilename(file), index) {
				return true
			}
		}
	}
	return false
}
예제 #6
0
func Create(source, target string, tt TargetType) error {
	srcp, err := syscall.UTF16PtrFromString(source)
	if err != nil {
		return err
	}

	trgp, err := syscall.UTF16PtrFromString(osutil.NativeFilename(target))
	if err != nil {
		return err
	}

	// Sadly for Windows we need to specify the type of the symlink,
	// whether it's a directory symlink or a file symlink.
	// If the flags doesn't reveal the target type, try to evaluate it
	// ourselves, and worst case default to the symlink pointing to a file.
	mode := 0
	if tt == TargetUnknown {
		path := target
		if !filepath.IsAbs(target) {
			path = filepath.Join(filepath.Dir(source), target)
		}

		stat, err := os.Stat(path)
		if err == nil && stat.IsDir() {
			mode = Win32SymbolicLinkFlagDirectory
		}
	} else if tt == TargetDirectory {
		mode = Win32SymbolicLinkFlagDirectory
	}

	r0, _, err := syscall.Syscall(procCreateSymbolicLink.Addr(), 3, uintptr(unsafe.Pointer(srcp)), uintptr(unsafe.Pointer(trgp)), uintptr(mode))
	if r0 == 1 {
		return nil
	}
	return err
}
예제 #7
0
파일: set.go 프로젝트: hernad/syncthing
func (s *FileSet) Get(device protocol.DeviceID, file string) (protocol.FileInfo, bool) {
	f, ok := s.db.getFile([]byte(s.folder), device[:], []byte(osutil.NormalizedFilename(file)))
	f.Name = osutil.NativeFilename(f.Name)
	return f, ok
}
예제 #8
0
func Create(source, target string, tt TargetType) error {
	return os.Symlink(osutil.NativeFilename(target), source)
}