func makeHardlinks(hardlinksToMake []sub.Hardlink, rootDirectoryName string, triggers *triggers.Triggers, tmpDir string, takeAction bool, logger *log.Logger) { tmpName := path.Join(tmpDir, "temporaryHardlink") for _, hardlink := range hardlinksToMake { triggers.Match(hardlink.NewLink) if takeAction { targetPathname := path.Join(rootDirectoryName, hardlink.Target) linkPathname := path.Join(rootDirectoryName, hardlink.NewLink) // A Link directly to linkPathname will fail if it exists, so do a // Link+Rename using a temporary filename. if err := fsutil.ForceLink(targetPathname, tmpName); err != nil { logger.Println(err) continue } if err := fsutil.ForceRename(tmpName, linkPathname); err != nil { logger.Println(err) if err := fsutil.ForceRemove(tmpName); err != nil { logger.Println(err) } } else { logger.Printf("Linked: %s => %s\n", linkPathname, targetPathname) } } } }
func convertToObject(pathname, objectsDir string) error { file, err := os.Open(pathname) if err != nil { return err } defer file.Close() hasher := sha512.New() _, err = io.Copy(hasher, file) if err != nil { return err } var hashVal hash.Hash copy(hashVal[:], hasher.Sum(nil)) objPathname := path.Join(objectsDir, objectcache.HashToFilename(hashVal)) if err = os.MkdirAll(path.Dir(objPathname), 0755); err != nil { return err } return fsutil.ForceRename(pathname, objPathname) }
func makeRegularInode(fullPathname string, inode *filesystem.RegularInode, multiplyUsedObjects map[hash.Hash]uint64, objectsDir string, logger *log.Logger) error { var objectPathname string if inode.Size > 0 { objectPathname = path.Join(objectsDir, objectcache.HashToFilename(inode.Hash)) numCopies := multiplyUsedObjects[inode.Hash] if numCopies > 1 { numCopies-- objectPathname += fmt.Sprintf("~%d~", numCopies) if numCopies < 2 { delete(multiplyUsedObjects, inode.Hash) } else { multiplyUsedObjects[inode.Hash] = numCopies } } } else { objectPathname = fmt.Sprintf("%s.empty.%d", fullPathname, os.Getpid()) if file, err := os.OpenFile(objectPathname, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600); err != nil { return err } else { file.Close() } } if err := fsutil.ForceRename(objectPathname, fullPathname); err != nil { logger.Println(err) return err } if err := inode.WriteMetadata(fullPathname); err != nil { logger.Println(err) return err } else { if inode.Size > 0 { logger.Printf("Made inode: %s from: %x\n", fullPathname, inode.Hash) } else { logger.Printf("Made empty inode: %s\n", fullPathname) } } return nil }
func makeRegularInode(fullPathname string, inode *filesystem.RegularInode, multiplyUsedObjects map[hash.Hash]uint64, objectsDir string, logger *log.Logger) { var err error if inode.Size > 0 { objectPathname := path.Join(objectsDir, objectcache.HashToFilename(inode.Hash)) numCopies := multiplyUsedObjects[inode.Hash] if numCopies > 1 { numCopies-- objectPathname += strings.Repeat("~", int(numCopies)) if numCopies < 2 { delete(multiplyUsedObjects, inode.Hash) } else { multiplyUsedObjects[inode.Hash] = numCopies } } err = fsutil.ForceRename(objectPathname, fullPathname) } else { _, err = os.Create(fullPathname) } if err != nil { logger.Println(err) return } if err := inode.WriteMetadata(fullPathname); err != nil { logger.Println(err) } else { if inode.Size > 0 { logger.Printf("Made inode: %s from: %x\n", fullPathname, inode.Hash) } else { logger.Printf("Made empty inode: %s\n", fullPathname) } } }