Пример #1
0
func mainStatus(args []string) int {
	f := flag.NewFlagSet("status", flag.ExitOnError)
	opt_no_par2 := f.Bool("n", false, "Do not show files missing PAR2 redundency data")
	opt_show_only_hash := f.Bool("c", false, "Show only unchanged committed files with their hash")
	opt_no_docignore := f.Bool("no-docignore", false, "Don't treat .docignore files specially")
	f.Usage = func() {
		fmt.Print(usageStatus)
		f.PrintDefaults()
	}
	f.Parse(args)
	dir := f.Arg(0)
	if dir == "" {
		dir = "."
	}

	rep := repo.GetRepo(dir)

	status := 0

	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s: %v\n", path, err.Error())
			status = 1
			return err
		}

		// Skip directories containing an empty .docignore file
		if !*opt_no_docignore && ignore.IsIgnored(path) {
			return filepath.SkipDir
		}

		// Skip .dirstore/ at root
		if filepath.Base(path) == attrs.DirStoreName && filepath.Dir(path) == dir && info.IsDir() {
			return filepath.SkipDir
		} else if !info.Mode().IsRegular() {
			return nil
		}

		if *opt_show_only_hash {
			hash, err := repo.GetHash(path, info, false)
			if err != nil {
				fmt.Fprintf(os.Stderr, "%s: %v\n", path, err.Error())
				return nil
			}

			if hash != nil {
				fmt.Printf("%s\t%s\n", base58.Encode(hash), path)
			}

		} else {

			var conflict string = ""
			if repo.ConflictFile(path) != "" {
				conflict = " c"
			} else if len(repo.ConflictFileAlternatives(path)) > 0 {
				conflict = " C"
			}

			hashTime, err := repo.GetHashTime(path)
			if repo.IsNoData(err) {
				if info.Mode()&os.FileMode(0200) == 0 {
					fmt.Printf("?%s (ro)\t%s\n", conflict, path)
				} else {
					fmt.Printf("?%s\t%s\n", conflict, path)
				}
				return nil
			} else if err != nil {
				fmt.Fprintf(os.Stderr, "%s: %v\n", path, err.Error())
				return nil
			}

			var redundency string = "*"
			if rep != nil {
				digest, err := repo.GetHash(path, info, true)
				if err != nil {
					fmt.Fprintf(os.Stderr, "%s: %v\n", path, err.Error())
					return nil
				}
				if par2exists, _ := rep.Par2Exists(digest); par2exists {
					redundency = ""
				}
			}

			if hashTime != info.ModTime() {
				fmt.Printf("+%s%s\t%s\n", conflict, redundency, path)
			} else if conflict != "" || (redundency != "" && !*opt_no_par2) {
				fmt.Printf("%s%s\t%s\n", conflict, redundency, path)
			}
		}

		return nil
	})

	if err != nil {
		fmt.Fprintf(os.Stderr, "%v", err)
		os.Exit(1)
	}
	return status
}
Пример #2
0
func mainInfo(args []string) int {
	f := flag.NewFlagSet("info", flag.ExitOnError)
	opt_check := f.Bool("c", false, "Run integrity check")
	f.Usage = func() {
		fmt.Print(infoUsage)
		f.PrintDefaults()
	}
	f.Parse(args)
	dir := f.Arg(0)
	if dir == "" {
		dir = "."
	}

	rep := repo.GetRepo(dir)

	status := 0
	first := true

	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			fmt.Fprintf(os.Stderr, "%s: %v\n", path, err.Error())
			status = 1
			return err
		}

		// Skip .dirstore/ at root
		if filepath.Base(path) == attrs.DirStoreName && filepath.Dir(path) == dir && info.IsDir() {
			return filepath.SkipDir
		} else if !info.Mode().IsRegular() {
			return nil
		}

		if first {
			first = false
		} else {
			fmt.Println()
		}

		fmt.Printf("File: %s\n", path)

		if conflict := repo.ConflictFile(path); conflict != "" {
			fmt.Printf("Conflict With: %s\n", conflict)
		}

		for _, alt := range repo.ConflictFileAlternatives(path) {
			fmt.Printf("Conflict Alternatives: %s\n", alt)
		}

		var realHash mh.Multihash
		if *opt_check {
			realHash, err = repo.HashFile(path, info)
			if err != nil {
				fmt.Fprintf(os.Stderr, "%s: %v\n", path, err)
				return nil
			}
		}

		hashTime, err := repo.GetHashTime(path)

		if repo.IsNoData(err) {
			if *opt_check {
				fmt.Printf("Actual Hash: %s\n", base58.Encode(realHash))
			}
			fmt.Printf("Status: New\n")
		} else {
			if err != nil {
				fmt.Fprintf(os.Stderr, "%s: %v\n", path, err.Error())
				return nil
			}

			fmt.Printf("Hash Time: %v\n", hashTime.Format(time.RFC3339Nano))

			hash, err := attrs.Get(path, repo.XattrHash)
			if err != nil {
				fmt.Fprintf(os.Stderr, "%s: %v\n", path, err)
				return nil
			}
			var par2exists = false
			if rep != nil {
				par2exists, _ = rep.Par2Exists(hash)
			}
			fmt.Printf("Recorded Hash: %s (reduncency %s)\n", base58.Encode(hash), boolToAvailableStr(par2exists))
			if *opt_check {
				par2exists = false
				if rep != nil {
					par2exists, _ = rep.Par2Exists(realHash)
				}
				fmt.Printf("Actual Hash:   %s (redundency %s)\n", base58.Encode(realHash), boolToAvailableStr(par2exists))
			}

			if hashTime != info.ModTime() {
				fmt.Printf("Status: Dirty\n")
			} else {
				if *opt_check && !bytes.Equal(realHash, hash) {
					fmt.Printf("Status: Corrupted\n")
				} else {
					fmt.Printf("Status: Clean\n")
				}
			}
		}

		return nil
	})

	if err != nil {
		fmt.Fprintf(os.Stderr, "%v", err)
		os.Exit(1)
	}
	return status
}