Beispiel #1
0
func (t *Trashcan) cleanoutArchive() error {
	versionsDir := filepath.Join(t.folderPath, ".stversions")
	if _, err := osutil.Lstat(versionsDir); os.IsNotExist(err) {
		return nil
	}

	cutoff := time.Now().Add(time.Duration(-24*t.cleanoutDays) * time.Hour)
	currentDir := ""
	filesInDir := 0
	walkFn := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if info.IsDir() {
			// We have entered a new directory. Lets check if the previous
			// directory was empty and try to remove it. We ignore failure for
			// the time being.
			if currentDir != "" && filesInDir == 0 {
				osutil.Remove(currentDir)
			}
			currentDir = path
			filesInDir = 0
			return nil
		}

		if info.ModTime().Before(cutoff) {
			// The file is too old; remove it.
			osutil.Remove(path)
		} else {
			// Keep this file, and remember it so we don't unnecessarily try
			// to remove this directory.
			filesInDir++
		}
		return nil
	}

	if err := filepath.Walk(versionsDir, walkFn); err != nil {
		return err
	}

	// The last directory seen by the walkFn may not have been removed as it
	// should be.
	if currentDir != "" && filesInDir == 0 {
		osutil.Remove(currentDir)
	}
	return nil
}
Beispiel #2
0
func (p *rwFolder) moveForConflict(name string) error {
	if strings.Contains(filepath.Base(name), ".sync-conflict-") {
		l.Infoln("Conflict for", name, "which is already a conflict copy; not copying again.")
		if err := osutil.Remove(name); err != nil && !os.IsNotExist(err) {
			return err
		}
		return nil
	}

	if p.maxConflicts == 0 {
		if err := osutil.Remove(name); err != nil && !os.IsNotExist(err) {
			return err
		}
		return nil
	}

	ext := filepath.Ext(name)
	withoutExt := name[:len(name)-len(ext)]
	newName := withoutExt + time.Now().Format(".sync-conflict-20060102-150405") + ext
	err := os.Rename(name, newName)
	if os.IsNotExist(err) {
		// We were supposed to move a file away but it does not exist. Either
		// the user has already moved it away, or the conflict was between a
		// remote modification and a local delete. In either way it does not
		// matter, go ahead as if the move succeeded.
		err = nil
	}
	if p.maxConflicts > -1 {
		matches, gerr := osutil.Glob(withoutExt + ".sync-conflict-????????-??????" + ext)
		if gerr == nil && len(matches) > p.maxConflicts {
			sort.Sort(sort.Reverse(sort.StringSlice(matches)))
			for _, match := range matches[p.maxConflicts:] {
				gerr = osutil.Remove(match)
				if gerr != nil {
					l.Debugln(p, "removing extra conflict", gerr)
				}
			}
		} else if gerr != nil {
			l.Debugln(p, "globbing for conflicts", gerr)
		}
	}
	return err
}