Example #1
0
func Directories(me *utils.Repository, path string, t time.Time) ([]string, error) {
	workingdir := filepath.Join(me.BasePath, types.DATA, types.INCREMENTS, path)
	resultset := make([]string, 0)
	times, err := me.TimeStamps()
	if err != nil {
		return nil, fmt.Errorf("unable to retrieve timestamps", types.DATA, err)
	}

	directories, err := ioutil.ReadDir(workingdir)
	if err != nil {
		return nil, fmt.Errorf("unable to parse directory", workingdir, err)
	}

	metafiles := make([]string, 0, len(directories))
	for _, e := range directories {
		if e.IsDir() {
			continue
		}
		if filepath.Ext(e.Name()) != ".dir" && filepath.Ext(e.Name()) != ".missing" {
			continue
		}
		unquote, err := utils.Unquote(e.Name())
		if err != nil {
			return nil, err
		}
		metafiles = append(metafiles, unquote)
	}

	for i, _ := range directories {
		if !directories[i].IsDir() {
			continue
		}

		lastchange := ""
		addflag := false
		for _, e := range times {
			addflag = false

			unquoted, err := utils.Unquote(e)
			if err != nil {
				return nil, err
			}
			parsedtime, err := time.Parse(types.TIMESTAMP_FMT, unquoted)
			if err != nil {
				return nil, fmt.Errorf("unable to parse time", e, err)
			}

			// t >= parsedtime
			if t.After(parsedtime) {
				exists := utils.StringInSlice(directories[i].Name()+"."+unquoted+types.DIR, metafiles)
				if !exists {
					continue
				}
				lastchange = unquoted
				continue
			}

			direxists := utils.StringInSlice(directories[i].Name()+"."+unquoted+types.DIR, metafiles)
			missingexists := utils.StringInSlice(directories[i].Name()+"."+unquoted+types.MISSING, metafiles)

			if t.Equal(parsedtime) {
				if !direxists && !missingexists {
					// if there is no such files, there is nothing to do
					continue
				} else if !missingexists && direxists {
					// there exists a .dir file in present time
					lastchange = unquoted
					continue
				} else if missingexists && !direxists {
					// there exist a .missing file in present time
					// file was created right on requested point of time, we take it
					resultset = append(resultset, directories[i].Name())
					lastchange = ""
					addflag = true
					break
				}
			}

			if t.Before(parsedtime) {
				if !direxists && !missingexists {
					// if there is non of such files, there is nothing to do
					continue
				} else if !direxists && missingexists {
					// .missing exists, that means directory was created after current point of time, we dont take it
					// toogled addflag, with an empty lastchange means the directory will not be added
					addflag = true
					break
				} else if direxists && !missingexists {
					// there exists a change on that directory after the current point of time, so it has to be available
					resultset = append(resultset, directories[i].Name())
					lastchange = ""
					addflag = true
					break
				}
			}
		}
		// if addflag is not set we have to check if the last change was a delete
		if !addflag && lastchange != "" {
			nextSnap, err := me.NextSnapshot(lastchange)
			if err != nil {
				return nil, fmt.Errorf("unable to retrieve next snapshot", err)
			}
			snapshot, err := os.Open(filepath.Join(me.DirectoryStructure, nextSnap+types.DIREXT))
			if err != nil {
				return nil, fmt.Errorf("unable to open directorie structure file")
			}
			if !me.Contains(filepath.Join(path, directories[i].Name()), snapshot) {
				continue
			}
			if err != nil {
				return nil, fmt.Errorf("unable to stat in directory", filepath.Join(me.DirectoryStructure, nextSnap+".structure", path))
			}
		}
		if addflag && lastchange == "" {
			continue
		}

		// passed all checks, add it
		resultset = append(resultset, directories[i].Name())
	}
	return resultset, nil
}
Example #2
0
func Files(me *utils.Repository, path string, t time.Time) ([]string, error) {
	workingdir := filepath.Join(me.BasePath, types.DATA, types.INCREMENTS, path)
	times, err := me.TimeStamps()
	if err != nil {
		return nil, fmt.Errorf("Unable to retrieve timestamps", types.DATA, err)
	}

	_, err = os.Stat(filepath.Join(me.BasePath, path))
	files := []os.FileInfo{}
	if err == nil {
		files, err = ioutil.ReadDir(filepath.Join(me.BasePath, path))
		if err != nil {
			return nil, fmt.Errorf("unable to parse directory", filepath.Join(me.BasePath, path), err)
		}
	}

	increments, err := ioutil.ReadDir(filepath.Join(me.BasePath, types.DATA, types.INCREMENTS, path))
	if err != nil {
		return nil, fmt.Errorf("unable to parse directory", filepath.Join(me.BasePath, types.DATA, types.INCREMENTS, path), err)
	}

	resultsetphy, err := FilterFiles(files, increments, times, t, workingdir)
	if err != nil {
		return nil, err
	}

	// deleted files are not to be found in the physical representation of files
	var filesinc []os.FileInfo
	for i, _ := range increments {
		if increments[i].IsDir() {
			continue
		}
		if filepath.Ext(utils.TrimExt(increments[i].Name())) != ".snapshot" {
			continue
		}

		needle := utils.TrimExt(utils.TrimExt(utils.TrimExt(increments[i].Name())))
		d, err := os.Stat(filepath.Join(me.BasePath, types.DATA, types.INCREMENTS, path, needle))
		if err == nil && d.IsDir() {
			// points to a directory, ignore this file
			continue
		} else if err != nil && !os.IsNotExist(err) {
			// real error case
			return nil, fmt.Errorf("unable to stat file", needle, err)
		}
		// check if resultphy already contains this file
		flag := false
		for _, e := range resultsetphy {
			if e == needle {
				flag = true
				break
			}
		}
		if !flag {
			filesinc = append(filesinc, &types.RdiffFileInfo{Name_: needle, IsDir_: false})
		}
	}
	resultsetinc, err := FilterFiles(filesinc, increments, times, t, workingdir)
	if err != nil {
		return nil, err
	}

	resultset := make([]string, len(resultsetphy)+len(resultsetinc))
	copy(resultset, resultsetphy)
	copy(resultset[len(resultsetphy):], resultsetinc)

	return resultset, nil
}
func rdiffElements(w http.ResponseWriter, r *http.Request) {
	dest := ""
	if r.FormValue("dest") == "" && len(utils.SplitPath(html.UnescapeString(r.FormValue("path")))) > 0 {
		// we want to go up one directory
		dest = filepath.Dir(html.UnescapeString(r.FormValue("path")))
	} else {
		dest = filepath.Join(html.UnescapeString(r.FormValue("path")), html.UnescapeString(r.FormValue("dest")))
	}

	level := len(utils.SplitPath(dest))
	var data []byte
	var elements []element

	if level == 0 {
		elements = make([]element, len(repos))
		for i, e := range repos {
			elements[i] = element{e.Name, "DIR", "0", "0", true, dest}
		}
	}
	if level == 1 {
		name := utils.SplitPath(dest)[0]
		path := filepath.Join("repositories", name)
		repo := utils.Repository{
			filepath.Join(path, "basepath"),
			filepath.Join(path, "directorystructure"),
			filepath.Join(path, "origin"),
			name,
		}

		times, err := repo.TimeStamps()
		if err != nil {
			log.Panic(err)
		}

		elements = make([]element, len(times))
		for i, e := range times {
			u, err := utils.Unquote(e)
			if err != nil {
				log.Panic(err)
			}
			elements[i] = element{u, "DIR", "0", "0", true, dest}
		}
	}
	if level > 1 {
		name := utils.SplitPath(dest)[0]
		path := filepath.Join("repositories", name)
		repo := utils.Repository{
			filepath.Join(path, "basepath"),
			filepath.Join(path, "directorystructure"),
			filepath.Join(path, "origin"),
			name,
		}

		var p string
		if len(utils.SplitPath(dest)) == 2 {
			p = ""
		} else {
			for _, e := range utils.SplitPath(dest)[2:] {
				p = filepath.Join(p, e)
			}
		}
		time_, err := utils.Unquote(utils.SplitPath(dest)[1])
		if err != nil {
			log.Panic(err)
		}
		timepoint, err := time.Parse(types.TIMESTAMP_FMT, time_)
		if err != nil {
			log.Panic(err)
		}
		dirs, err := incs.Directories(&repo, p, timepoint)
		if err != nil {
			log.Panic(err)
		}
		files, err := incs.Files(&repo, p, timepoint)
		if err != nil {
			log.Panic(err)
		}
		elements = make([]element, len(dirs)+len(files))
		for i, e := range dirs {
			elements[i] = element{e, "DIR", "0", "0", true, dest}
		}
		for i, e := range files {
			elements[i+len(dirs)] = element{e, filepath.Ext(e), "0", "0", false, dest}
		}

		if len(elements) == 0 {
			elements = []element{element{"", "DUMMY0", "0", "0", false, dest}}
		}
	}

	data, err := json.Marshal(elements)
	if err != nil {
		log.Panic("unable to marshal table rows", err)
	}
	w.Write(data)
}