コード例 #1
0
ファイル: decode.go プロジェクト: keep94/Dominator
func (decoderData *decoderData) addSpecialFile(header *tar.Header,
	parent *filesystem.DirectoryInode, name string) error {
	var newInode filesystem.SpecialInode
	if header.Typeflag == tar.TypeChar {
		newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
			syscall.S_IFCHR)
	} else if header.Typeflag == tar.TypeBlock {
		newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
			syscall.S_IFBLK)
	} else if header.Typeflag == tar.TypeFifo {
		newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
			syscall.S_IFIFO)
	} else {
		return errors.New(fmt.Sprintf("unsupported type: %v", header.Typeflag))
	}
	newInode.Uid = uint32(header.Uid)
	newInode.Gid = uint32(header.Gid)
	newInode.MtimeNanoSeconds = int32(header.ModTime.Nanosecond())
	newInode.MtimeSeconds = header.ModTime.Unix()
	if header.Devminor > 255 {
		return errors.New(fmt.Sprintf("minor device number: %d too large",
			header.Devminor))
	}
	newInode.Rdev = uint64(header.Devmajor<<8 | header.Devminor)
	decoderData.addEntry(parent, header.Name, name, &newInode)
	return nil
}
コード例 #2
0
ファイル: decode.go プロジェクト: wxdublin/Dominator
func (decoderData *decoderData) addFile(header *tar.Header,
	parent *filesystem.Directory, name string) error {
	var newInode filesystem.Inode
	if header.Typeflag == tar.TypeChar {
		newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
			syscall.S_IFCHR)
	} else if header.Typeflag == tar.TypeBlock {
		newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
			syscall.S_IFBLK)
	} else if header.Typeflag == tar.TypeFifo {
		newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
			syscall.S_IFIFO)
	} else {
		return errors.New(fmt.Sprintf("unsupported type: %v", header.Typeflag))
	}
	newInode.Uid = uint32(header.Uid)
	newInode.Gid = uint32(header.Gid)
	newInode.MtimeNanoSeconds = int32(header.ModTime.Nanosecond())
	newInode.MtimeSeconds = header.ModTime.Unix()
	if header.Devminor > 255 {
		return errors.New(fmt.Sprintf("minor device number: %d too large",
			header.Devminor))
	}
	newInode.Rdev = uint64(header.Devmajor<<8 | header.Devminor)
	decoderData.inodeTable[header.Name] = decoderData.nextInodeNumber
	decoderData.fileSystem.InodeTable[decoderData.nextInodeNumber] =
		&newInode
	var newEntry filesystem.File
	newEntry.Name = name
	newEntry.InodeNumber = decoderData.nextInodeNumber
	parent.FileList = append(parent.FileList, &newEntry)
	decoderData.nextInodeNumber++
	return nil
}
コード例 #3
0
ファイル: walk.go プロジェクト: datatonic/Dominator
func addDirectory(dirent, oldDirent *filesystem.DirectoryEntry,
	fileSystem, oldFS *FileSystem,
	directoryPathName string, stat *syscall.Stat_t) error {
	myPathName := path.Join(directoryPathName, dirent.Name)
	if stat.Ino == fileSystem.inodeNumber {
		return errors.New("Recursive directory: " + myPathName)
	}
	if _, ok := fileSystem.InodeTable[stat.Ino]; ok {
		return errors.New("Hardlinked directory: " + myPathName)
	}
	inode := new(filesystem.DirectoryInode)
	dirent.SetInode(inode)
	fileSystem.InodeTable[stat.Ino] = inode
	inode.Mode = filesystem.FileMode(stat.Mode)
	inode.Uid = stat.Uid
	inode.Gid = stat.Gid
	var oldInode *filesystem.DirectoryInode
	if oldDirent != nil {
		if oi, ok := oldDirent.Inode().(*filesystem.DirectoryInode); ok {
			oldInode = oi
		}
	}
	err, copied := scanDirectory(inode, oldInode, fileSystem, oldFS, myPathName)
	if err != nil {
		return err
	}
	if copied && filesystem.CompareDirectoriesMetadata(inode, oldInode, nil) {
		dirent.SetInode(oldInode)
		fileSystem.InodeTable[stat.Ino] = oldInode
	}
	fileSystem.DirectoryCount++
	return nil
}
コード例 #4
0
ファイル: walk.go プロジェクト: datatonic/Dominator
func makeSpecialInode(stat *syscall.Stat_t) *filesystem.SpecialInode {
	var inode filesystem.SpecialInode
	inode.Mode = filesystem.FileMode(stat.Mode)
	inode.Uid = stat.Uid
	inode.Gid = stat.Gid
	inode.MtimeSeconds = stat.Mtim.Sec
	inode.MtimeNanoSeconds = int32(stat.Mtim.Nsec)
	inode.Rdev = stat.Rdev
	return &inode
}
コード例 #5
0
ファイル: walk.go プロジェクト: datatonic/Dominator
func makeRegularInode(stat *syscall.Stat_t) *filesystem.RegularInode {
	var inode filesystem.RegularInode
	inode.Mode = filesystem.FileMode(stat.Mode)
	inode.Uid = stat.Uid
	inode.Gid = stat.Gid
	inode.MtimeSeconds = stat.Mtim.Sec
	inode.MtimeNanoSeconds = int32(stat.Mtim.Nsec)
	inode.Size = uint64(stat.Size)
	return &inode
}
コード例 #6
0
ファイル: decode.go プロジェクト: wxdublin/Dominator
func (decoderData *decoderData) addDirectory(header *tar.Header,
	parent *filesystem.Directory, name string) error {
	var newEntry filesystem.Directory
	newEntry.Name = name
	newEntry.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
		syscall.S_IFDIR)
	newEntry.Uid = uint32(header.Uid)
	newEntry.Gid = uint32(header.Gid)
	parent.DirectoryList = append(parent.DirectoryList, &newEntry)
	decoderData.directoryTable[header.Name] = &newEntry
	return nil
}
コード例 #7
0
ファイル: pushFile.go プロジェクト: keep94/Dominator
func pushFile(getSubClient getSubClientFunc, source, dest string) error {
	var sourceStat wsyscall.Stat_t
	if err := wsyscall.Stat(source, &sourceStat); err != nil {
		return err
	}
	sourceFile, err := os.Open(source)
	if err != nil {
		return err
	}
	defer sourceFile.Close()
	srpcClient := getSubClient()
	objClient := objclient.AttachObjectClient(srpcClient)
	defer objClient.Close()
	if err != nil {
		return err
	}
	hashVal, _, err := objClient.AddObject(sourceFile, uint64(sourceStat.Size),
		nil)
	if err != nil {
		return err
	}
	newRegularInode := &filesystem.RegularInode{
		Mode:             filesystem.FileMode(sourceStat.Mode),
		Uid:              sourceStat.Uid,
		Gid:              sourceStat.Gid,
		MtimeNanoSeconds: int32(sourceStat.Mtim.Nsec),
		MtimeSeconds:     sourceStat.Mtim.Sec,
		Size:             uint64(sourceStat.Size),
		Hash:             hashVal}
	newInode := sub.Inode{Name: dest, GenericInode: newRegularInode}
	var updateRequest sub.UpdateRequest
	var updateReply sub.UpdateResponse
	updateRequest.Wait = true
	updateRequest.InodesToMake = append(updateRequest.InodesToMake, newInode)
	if *triggersFile != "" {
		updateRequest.Triggers, err = triggers.Load(*triggersFile)
		if err != nil {
			return err
		}
	} else if *triggersString != "" {
		updateRequest.Triggers, err = triggers.Decode([]byte(*triggersString))
		if err != nil {
			return err
		}
	}
	startTime := showStart("Subd.Update()")
	err = client.CallUpdate(srpcClient, updateRequest, &updateReply)
	showTimeTaken(startTime)
	return err
}
コード例 #8
0
ファイル: decode.go プロジェクト: keep94/Dominator
func (decoderData *decoderData) addDirectory(header *tar.Header,
	parent *filesystem.DirectoryInode, name string) error {
	var newInode filesystem.DirectoryInode
	newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
		syscall.S_IFDIR)
	newInode.Uid = uint32(header.Uid)
	newInode.Gid = uint32(header.Gid)
	if header.Name == "/" {
		*decoderData.directoryTable[header.Name] = newInode
		return nil
	}
	decoderData.addEntry(parent, header.Name, name, &newInode)
	decoderData.directoryTable[header.Name] = &newInode
	return nil
}
コード例 #9
0
ファイル: walk.go プロジェクト: keep94/Dominator
func scanFileSystem(rootDirectoryName string,
	fsScanContext *fsrateio.ReaderContext, scanFilter *filter.Filter,
	checkScanDisableRequest func() bool, hasher Hasher, oldFS *FileSystem) (
	*FileSystem, error) {
	var fileSystem FileSystem
	fileSystem.rootDirectoryName = rootDirectoryName
	fileSystem.fsScanContext = fsScanContext
	fileSystem.scanFilter = scanFilter
	fileSystem.checkScanDisableRequest = checkScanDisableRequest
	if hasher == nil {
		fileSystem.hasher = GetSimpleHasher(false)
	} else {
		fileSystem.hasher = hasher
	}
	var stat wsyscall.Stat_t
	if err := wsyscall.Lstat(rootDirectoryName, &stat); err != nil {
		return nil, err
	}
	fileSystem.InodeTable = make(filesystem.InodeTable)
	fileSystem.dev = stat.Dev
	fileSystem.inodeNumber = stat.Ino
	fileSystem.Mode = filesystem.FileMode(stat.Mode)
	fileSystem.Uid = stat.Uid
	fileSystem.Gid = stat.Gid
	fileSystem.DirectoryCount++
	var tmpInode filesystem.RegularInode
	if sha512.New().Size() != len(tmpInode.Hash) {
		return nil, errors.New("incompatible hash size")
	}
	var oldDirectory *filesystem.DirectoryInode
	if oldFS != nil && oldFS.InodeTable != nil {
		oldDirectory = &oldFS.DirectoryInode
	}
	err, _ := scanDirectory(&fileSystem.FileSystem.DirectoryInode, oldDirectory,
		&fileSystem, oldFS, "/")
	oldFS = nil
	oldDirectory = nil
	if err != nil {
		return nil, err
	}
	fileSystem.ComputeTotalDataBytes()
	if err = fileSystem.RebuildInodePointers(); err != nil {
		panic(err)
	}
	return &fileSystem, nil
}
コード例 #10
0
ファイル: walk.go プロジェクト: wxdublin/Dominator
func (fileSystem *FileSystem) getInode(stat *syscall.Stat_t) (
	*filesystem.Inode, bool) {
	inode := fileSystem.InodeTable[stat.Ino]
	new := false
	if inode == nil {
		var _inode filesystem.Inode
		inode = &_inode
		_inode.Mode = filesystem.FileMode(stat.Mode)
		_inode.Uid = stat.Uid
		_inode.Gid = stat.Gid
		_inode.MtimeSeconds = stat.Mtim.Sec
		_inode.MtimeNanoSeconds = int32(stat.Mtim.Nsec)
		_inode.Rdev = stat.Rdev
		fileSystem.InodeTable[stat.Ino] = inode
		new = true
	}
	return inode, new
}
コード例 #11
0
ファイル: walk.go プロジェクト: wxdublin/Dominator
func addDirectory(directory *filesystem.Directory,
	fileSystem, oldFS *FileSystem,
	name string, directoryPathName string, stat *syscall.Stat_t) error {
	myPathName := path.Join(directoryPathName, name)
	if fileSystem.directoryInodeList[stat.Ino] {
		return errors.New("Hardlinked directory: " + myPathName)
	}
	fileSystem.directoryInodeList[stat.Ino] = true
	var dir filesystem.Directory
	dir.Name = name
	dir.Mode = filesystem.FileMode(stat.Mode)
	dir.Uid = stat.Uid
	dir.Gid = stat.Gid
	err := scanDirectory(&dir, fileSystem, oldFS, directoryPathName)
	if err != nil {
		return err
	}
	directory.DirectoryList = append(directory.DirectoryList, &dir)
	return nil
}
コード例 #12
0
ファイル: walk.go プロジェクト: datatonic/Dominator
func scanFileSystem(rootDirectoryName string, cacheDirectoryName string,
	configuration *Configuration, oldFS *FileSystem) (*FileSystem, error) {
	var fileSystem FileSystem
	fileSystem.configuration = configuration
	fileSystem.rootDirectoryName = rootDirectoryName
	fileSystem.cacheDirectoryName = cacheDirectoryName
	var stat syscall.Stat_t
	if err := syscall.Lstat(rootDirectoryName, &stat); err != nil {
		return nil, err
	}
	fileSystem.InodeTable = make(filesystem.InodeTable)
	fileSystem.dev = stat.Dev
	fileSystem.inodeNumber = stat.Ino
	fileSystem.Mode = filesystem.FileMode(stat.Mode)
	fileSystem.Uid = stat.Uid
	fileSystem.Gid = stat.Gid
	fileSystem.DirectoryCount++
	var tmpInode filesystem.RegularInode
	if sha512.New().Size() != len(tmpInode.Hash) {
		return nil, errors.New("Incompatible hash size")
	}
	var oldDirectory *filesystem.DirectoryInode
	if oldFS != nil && oldFS.InodeTable != nil {
		oldDirectory = &oldFS.DirectoryInode
	}
	err, _ := scanDirectory(&fileSystem.FileSystem.DirectoryInode, oldDirectory,
		&fileSystem, oldFS, "/")
	oldFS = nil
	oldDirectory = nil
	if err != nil {
		return nil, err
	}
	if err = fileSystem.scanObjectCache(); err != nil {
		return nil, err
	}
	fileSystem.ComputeTotalDataBytes()
	if err = fileSystem.RebuildInodePointers(); err != nil {
		panic(err)
	}
	return &fileSystem, nil
}
コード例 #13
0
ファイル: decode.go プロジェクト: keep94/Dominator
func (decoderData *decoderData) addRegularFile(tarReader *tar.Reader,
	hasher Hasher, header *tar.Header, parent *filesystem.DirectoryInode,
	name string) error {
	var newInode filesystem.RegularInode
	newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
		syscall.S_IFREG)
	newInode.Uid = uint32(header.Uid)
	newInode.Gid = uint32(header.Gid)
	newInode.MtimeNanoSeconds = int32(header.ModTime.Nanosecond())
	newInode.MtimeSeconds = header.ModTime.Unix()
	newInode.Size = uint64(header.Size)
	if header.Size > 0 {
		var err error
		newInode.Hash, err = hasher.Hash(tarReader, uint64(header.Size))
		if err != nil {
			return err
		}
	}
	decoderData.addEntry(parent, header.Name, name, &newInode)
	return nil
}
コード例 #14
0
ファイル: walk.go プロジェクト: wxdublin/Dominator
func scanFileSystem(rootDirectoryName string, cacheDirectoryName string,
	configuration *Configuration, oldFS *FileSystem) (*FileSystem, error) {
	var fileSystem FileSystem
	fileSystem.configuration = configuration
	fileSystem.rootDirectoryName = rootDirectoryName
	fileSystem.cacheDirectoryName = cacheDirectoryName
	fileSystem.Name = "/"
	var stat syscall.Stat_t
	err := syscall.Lstat(rootDirectoryName, &stat)
	if err != nil {
		return nil, err
	}
	fileSystem.RegularInodeTable = make(filesystem.RegularInodeTable)
	fileSystem.SymlinkInodeTable = make(filesystem.SymlinkInodeTable)
	fileSystem.InodeTable = make(filesystem.InodeTable)
	fileSystem.directoryInodeList = make(directoryInodeList)
	fileSystem.directoryInodeList[stat.Ino] = true
	fileSystem.dev = stat.Dev
	fileSystem.Mode = filesystem.FileMode(stat.Mode)
	fileSystem.Uid = stat.Uid
	fileSystem.Gid = stat.Gid
	var tmpInode filesystem.RegularInode
	if sha512.New().Size() != len(tmpInode.Hash) {
		return nil, errors.New("Incompatible hash size")
	}
	err = scanDirectory(&fileSystem.FileSystem.Directory, &fileSystem, oldFS,
		"")
	oldFS = nil
	fileSystem.DirectoryCount = uint64(len(fileSystem.directoryInodeList))
	fileSystem.directoryInodeList = nil
	if err != nil {
		return nil, err
	}
	err = fileSystem.scanObjectCache()
	if err != nil {
		return nil, err
	}
	fileSystem.ComputeTotalDataBytes()
	return &fileSystem, nil
}
コード例 #15
0
ファイル: decode.go プロジェクト: wxdublin/Dominator
func (decoderData *decoderData) addRegularFile(tarReader *tar.Reader,
	dataHandler DataHandler, header *tar.Header, parent *filesystem.Directory,
	name string) error {
	var newInode filesystem.RegularInode
	newInode.Mode = filesystem.FileMode((header.Mode & ^syscall.S_IFMT) |
		syscall.S_IFREG)
	newInode.Uid = uint32(header.Uid)
	newInode.Gid = uint32(header.Gid)
	newInode.MtimeNanoSeconds = int32(header.ModTime.Nanosecond())
	newInode.MtimeSeconds = header.ModTime.Unix()
	newInode.Size = uint64(header.Size)
	if header.Size > 0 {
		data, err := ioutil.ReadAll(tarReader)
		if err != nil {
			return errors.New("error reading file data" + err.Error())
		}
		if int64(len(data)) != header.Size {
			return errors.New(fmt.Sprintf(
				"failed to read file data, wanted: %d, got: %d bytes",
				header.Size, len(data)))
		}
		newInode.Hash, err = dataHandler.HandleData(data)
		if err != nil {
			return err
		}
	}
	decoderData.regularInodeTable[header.Name] = decoderData.nextInodeNumber
	decoderData.fileSystem.RegularInodeTable[decoderData.nextInodeNumber] =
		&newInode
	var newEntry filesystem.RegularFile
	newEntry.Name = name
	newEntry.InodeNumber = decoderData.nextInodeNumber
	parent.RegularFileList = append(parent.RegularFileList, &newEntry)
	decoderData.nextInodeNumber++
	return nil
}