예제 #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
}
예제 #2
0
func FilterFiles(files, increments []os.FileInfo, times []string, t time.Time, workingdir string) ([]string, error) {
	resultset := make([]string, 0)
	metafiles := make([]string, 0, len(files))
	for _, e := range increments {
		if e.IsDir() {
			continue
		}
		if filepath.Ext(utils.TrimExt(e.Name())) != ".snapshot" && 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 files {
		if files[i].IsDir() {
			continue
		}

		break_ := false
		for _, e := range times {
			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) {

				if !utils.StringInSlice(files[i].Name()+"."+unquoted+".snapshot.gz", metafiles) {
					continue
				}

				// file was deleted in the past, dont add it to the resultset
				break_ = true
				break
			}

			if t.Before(parsedtime) || t.Equal(parsedtime) {
				if !utils.StringInSlice(files[i].Name()+"."+unquoted+".missing", metafiles) {
					continue
				}

				// file was created in the future, dont add it to the resultset
				break_ = true
				break
			}
		}
		if break_ {
			continue
		}
		resultset = append(resultset, files[i].Name())
	}

	return resultset, nil
}
예제 #3
0
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)
}