func saveConfigLoop(cfgFile string) { for _ = range saveConfigCh { fd, err := os.Create(cfgFile + ".tmp") if err != nil { l.Warnln("Saving config:", err) continue } err = config.Save(fd, cfg) if err != nil { l.Warnln("Saving config:", err) fd.Close() continue } err = fd.Close() if err != nil { l.Warnln("Saving config:", err) continue } err = osutil.Rename(cfgFile+".tmp", cfgFile) if err != nil { l.Warnln("Saving config:", err) } } }
func (cfg *Configuration) Save() error { fd, err := os.Create(cfg.Location + ".tmp") if err != nil { l.Warnln("Saving config:", err) return err } e := xml.NewEncoder(fd) e.Indent("", " ") err = e.Encode(cfg) if err != nil { fd.Close() return err } _, err = fd.Write([]byte("\n")) if err != nil { l.Warnln("Saving config:", err) fd.Close() return err } err = fd.Close() if err != nil { l.Warnln("Saving config:", err) return err } err = osutil.Rename(cfg.Location+".tmp", cfg.Location) if err != nil { l.Warnln("Saving config:", err) } events.Default.Log(events.ConfigSaved, cfg) return err }
func (p *puller) handleEmptyBlock(b bqBlock) { f := b.file of := p.openFiles[f.Name] if b.last { if of.err == nil { of.file.Close() } } if protocol.IsDeleted(f.Flags) { if debug { l.Debugf("pull: delete %q", f.Name) } os.Remove(of.temp) // Ensure the file and the directory it is in is writeable so we can remove the file dirName := filepath.Dir(of.filepath) os.Chmod(of.filepath, 0666) if dirName != p.repoCfg.Directory { os.Chmod(dirName, 0777) } if p.versioner != nil { if debug { l.Debugln("pull: deleting with versioner") } if err := p.versioner.Archive(p.repoCfg.Directory, of.filepath); err == nil { p.model.updateLocal(p.repoCfg.ID, f) } else if debug { l.Debugln("pull: error:", err) } } else if err := os.Remove(of.filepath); err == nil || os.IsNotExist(err) { p.model.updateLocal(p.repoCfg.ID, f) } } else { if debug { l.Debugf("pull: no blocks to fetch and nothing to copy for %q / %q", p.repoCfg.ID, f.Name) } t := time.Unix(f.Modified, 0) if os.Chtimes(of.temp, t, t) != nil { delete(p.openFiles, f.Name) return } if !p.repoCfg.IgnorePerms && protocol.HasPermissionBits(f.Flags) && os.Chmod(of.temp, os.FileMode(f.Flags&0777)) != nil { delete(p.openFiles, f.Name) return } osutil.ShowFile(of.temp) if osutil.Rename(of.temp, of.filepath) == nil { p.model.updateLocal(p.repoCfg.ID, f) } } delete(p.openFiles, f.Name) }
// Rename versions with old version format func (v Staggered) renameOld() { err := filepath.Walk(v.versionsPath, func(path string, f os.FileInfo, err error) error { if f.Mode().IsRegular() { versionUnix, err := strconv.ParseInt(strings.Replace(filepath.Ext(path), ".v", "", 1), 10, 0) if err == nil { l.Infoln("Renaming file", path, "from old to new version format") versiondate := time.Unix(versionUnix, 0) name := path[:len(path)-len(filepath.Ext(path))] err = osutil.Rename(path, name+"~"+versiondate.Format(TimeLayout)) if err != nil { l.Infoln("Error renaming to new format", err) } } } return nil }) if err != nil { l.Infoln("Versioner: error scanning versions dir", err) return } }
func saveCsrfTokens() { name := filepath.Join(confDir, "csrftokens.txt") tmp := fmt.Sprintf("%s.tmp.%d", name, time.Now().UnixNano()) f, err := os.OpenFile(tmp, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644) if err != nil { return } defer os.Remove(tmp) for _, t := range csrfTokens { _, err := fmt.Fprintln(f, t) if err != nil { return } } err = f.Close() if err != nil { return } osutil.Rename(tmp, name) }
func (p *puller) closeFile(f protocol.FileInfo) { if debug { l.Debugf("pull: closing %q / %q", p.repoCfg.ID, f.Name) } of := p.openFiles[f.Name] err := of.file.Close() if err != nil { p.errors++ l.Infof("close: error: %q / %q: %v", p.repoCfg.ID, f.Name, err) } defer os.Remove(of.temp) delete(p.openFiles, f.Name) fd, err := os.Open(of.temp) if err != nil { p.errors++ l.Infof("open: error: %q / %q: %v", p.repoCfg.ID, f.Name, err) return } hb, _ := scanner.Blocks(fd, scanner.StandardBlockSize, f.Size()) fd.Close() if l0, l1 := len(hb), len(f.Blocks); l0 != l1 { if debug { l.Debugf("pull: %q / %q: nblocks %d != %d", p.repoCfg.ID, f.Name, l0, l1) } return } for i := range hb { if bytes.Compare(hb[i].Hash, f.Blocks[i].Hash) != 0 { if debug { l.Debugf("pull: %q / %q: block %d hash mismatch\n have: %x\n want: %x", p.repoCfg.ID, f.Name, i, hb[i].Hash, f.Blocks[i].Hash) } return } } t := time.Unix(f.Modified, 0) err = os.Chtimes(of.temp, t, t) if err != nil { l.Infof("chtimes: error: %q / %q: %v", p.repoCfg.ID, f.Name, err) } if !p.repoCfg.IgnorePerms && protocol.HasPermissionBits(f.Flags) { err = os.Chmod(of.temp, os.FileMode(f.Flags&0777)) if err != nil { l.Infof("chmod: error: %q / %q: %v", p.repoCfg.ID, f.Name, err) } } osutil.ShowFile(of.temp) if p.versioner != nil { err := p.versioner.Archive(of.filepath) if err != nil { if debug { l.Debugf("pull: error: %q / %q: %v", p.repoCfg.ID, f.Name, err) } return } } if debug { l.Debugf("pull: rename %q / %q: %q", p.repoCfg.ID, f.Name, of.filepath) } if err := osutil.Rename(of.temp, of.filepath); err == nil { p.model.updateLocal(p.repoCfg.ID, f) } else { p.errors++ l.Infof("rename: error: %q / %q: %v", p.repoCfg.ID, f.Name, err) } }
// Move away the named file to a version archive. If this function returns // nil, the named file does not exist any more (has been archived). func (v Simple) Archive(repoPath, filePath string) error { _, err := os.Stat(filePath) if err != nil && os.IsNotExist(err) { if debug { l.Debugln("not archiving nonexistent file", filePath) } return nil } versionsDir := filepath.Join(repoPath, ".stversions") _, err = os.Stat(versionsDir) if err != nil { if os.IsNotExist(err) { if debug { l.Debugln("creating versions dir", versionsDir) } os.MkdirAll(versionsDir, 0755) osutil.HideFile(versionsDir) } else { return err } } if debug { l.Debugln("archiving", filePath) } file := filepath.Base(filePath) inRepoPath, err := filepath.Rel(repoPath, filepath.Dir(filePath)) if err != nil { return err } dir := filepath.Join(versionsDir, inRepoPath) err = os.MkdirAll(dir, 0755) if err != nil && !os.IsExist(err) { return err } ver := file + "~" + time.Now().Format("20060102-150405") dst := filepath.Join(dir, ver) if debug { l.Debugln("moving to", dst) } err = osutil.Rename(filePath, dst) if err != nil { return err } versions, err := filepath.Glob(filepath.Join(dir, file+"~*")) if err != nil { l.Warnln(err) return nil } if len(versions) > v.keep { sort.Strings(versions) for _, toRemove := range versions[:len(versions)-v.keep] { if debug { l.Debugln("cleaning out", toRemove) } err = os.Remove(toRemove) if err != nil { l.Warnln(err) } } } return nil }
// Move away the named file to a version archive. If this function returns // nil, the named file does not exist any more (has been archived). func (v Staggered) Archive(filePath string) error { if debug { l.Debugln("Waiting for lock on ", v.versionsPath) } v.mutex.Lock() defer v.mutex.Unlock() _, err := os.Stat(filePath) if err != nil { if os.IsNotExist(err) { if debug { l.Debugln("not archiving nonexistent file", filePath) } return nil } else { return err } } _, err = os.Stat(v.versionsPath) if err != nil { if os.IsNotExist(err) { if debug { l.Debugln("creating versions dir", v.versionsPath) } os.MkdirAll(v.versionsPath, 0755) osutil.HideFile(v.versionsPath) } else { return err } } if debug { l.Debugln("archiving", filePath) } file := filepath.Base(filePath) inRepoPath, err := filepath.Rel(v.repoPath, filepath.Dir(filePath)) if err != nil { return err } dir := filepath.Join(v.versionsPath, inRepoPath) err = os.MkdirAll(dir, 0755) if err != nil && !os.IsExist(err) { return err } ver := file + ".v" + fmt.Sprintf("%010d", time.Now().Unix()) dst := filepath.Join(dir, ver) if debug { l.Debugln("moving to", dst) } err = osutil.Rename(filePath, dst) if err != nil { return err } versions, err := filepath.Glob(filepath.Join(dir, file+".v[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]")) if err != nil { l.Warnln("Versioner: error finding versions for", file, err) return nil } sort.Strings(versions) v.expire(versions) return nil }
// Move away the named file to a version archive. If this function returns // nil, the named file does not exist any more (has been archived). func (v Staggered) Archive(filePath string) error { if debug { l.Debugln(logPrefix, "Waiting for lock on ", v.versionsPath) } v.mutex.Lock() defer v.mutex.Unlock() fileInfo, err := os.Stat(filePath) if err != nil { if os.IsNotExist(err) { if debug { l.Debugln(logPrefix, "not archiving nonexistent file", filePath) } return nil } else { return err } } _, err = os.Stat(v.versionsPath) if err != nil { if os.IsNotExist(err) { if debug { l.Debugln(logPrefix, "creating versions dir", v.versionsPath) } os.MkdirAll(v.versionsPath, 0755) osutil.HideFile(v.versionsPath) } else { return err } } if debug { l.Debugln(logPrefix, "archiving", filePath) } file := filepath.Base(filePath) inRepoPath, err := filepath.Rel(v.repoPath, filepath.Dir(filePath)) if err != nil { return err } dir := filepath.Join(v.versionsPath, inRepoPath) err = os.MkdirAll(dir, 0755) if err != nil && !os.IsExist(err) { return err } ver := file + "~" + fileInfo.ModTime().Format(TimeLayout) dst := filepath.Join(dir, ver) if debug { l.Debugln(logPrefix, "moving to", dst) } err = osutil.Rename(filePath, dst) if err != nil { return err } versions, err := filepath.Glob(filepath.Join(dir, file+"~[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]")) if err != nil { l.Warnln(logPrefix, "Versioner: error finding versions for", file, err) return nil } sort.Strings(versions) v.expire(versions) return nil }