예제 #1
0
func main() {
	PROG_NAME := filepath.Base(os.Args[0])

	var moveFiles bool
	flag.BoolVar(&moveFiles, "m", false, "move files to destination instead of copying")

	flag.Parse()

	if len(flag.Args()) < 2 {
		fmt.Printf("error: Invalid parameters\n")
		fmt.Printf("usage: %s [-m] dst src ...\n", PROG_NAME)
		os.Exit(ERR_INVALID_PARAMS)
	}

	// Initialize LevelDB
	var dbh *leveldb.DB

	if dbDir, err := ioutil.TempDir("", PROG_NAME); err != nil {
		fmt.Printf("error: Creation of tmp dir failed: %s\n", err)
		os.Exit(ERR_CREATE_TMP_DIR_FAILED)
	} else {
		defer cleanupDbDir(dbDir)
		dbh, err = leveldb.Open(dbDir, &db.Options{})

		if err != nil {
			fmt.Printf("error: Temporary working DB initialization failed: %s", err)
			os.Exit(ERR_OPEN_DB_FAILED)
		}

		defer dbh.Close()
	}

	// Create channels
	hashingCh := make(chan *fileEntry)
	defer close(hashingCh)

	processingCh := make(chan *fileEntry)

	// Go for it
	go hashFiles(hashingCh, processingCh)
	go processFile(dbh, processingCh, moveFiles)

	for _, d := range flag.Args()[1:] {
		filepath.Walk(d, getPathProcessor(hashingCh, d, flag.Args()[0]))
	}
}
예제 #2
0
func processFile(dbh *leveldb.DB, processingCh <-chan *fileEntry, move bool) {
	var fent *fileEntry
	more := true

	for more {
		select {
		case fent, more = <-processingCh:
			if more {

				if _, err := dbh.Get(fent.csum, nil); err == db.ErrNotFound {
					// file not processed yet
					if move {
						DEBUG("moving file %s to %s\n", fent.srcPath, fent.dstPath)

						if err = os.MkdirAll(filepath.Dir(fent.dstPath), (os.ModeDir | 0750)); err != nil {
							fmt.Printf("%s\n", err)
							continue
						}

						if err = os.Rename(fent.srcPath, fent.dstPath); err != nil {
							fmt.Printf("error: renaming file %s to %s failed. trying to copy instead.\n", fent.srcPath, fent.dstPath)
							if err = Copy(fent.srcPath, fent.dstPath); err != nil {
								fmt.Printf("error: Couldn't copy file %s to %s: %s\n", fent.srcPath, fent.dstPath, err)
								continue
							}
						}
					} else {
						DEBUG("copying file %s to %s\n", fent.srcPath, fent.dstPath)
						if err = Copy(fent.srcPath, fent.dstPath); err != nil {
							fmt.Printf("error: Couldn't copy file %s to %s: %s\n", fent.srcPath, fent.dstPath, err)
							continue
						}
					}

					dbh.Set(fent.csum, []byte(fent.srcPath), nil)
				} else if err == nil {
					DEBUG("skipping file %s since it already exists.\n", fent.srcPath)
				} else {
					fmt.Printf("error: Unable to check whether %s exists: %s. Skipping.\n", fent.srcPath, err)
					continue
				}
			}
		}
	}
}