예제 #1
2
func (f *Filesystem) shouldRead(filePath string, fi os.FileInfo) (bool, error) {
	if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
		link, err := filepath.EvalSymlinks(filePath)
		if err != nil {
			jww.ERROR.Printf("Cannot read symbolic link '%s', error was: %s", filePath, err)
			return false, nil
		}
		linkfi, err := os.Stat(link)
		if err != nil {
			jww.ERROR.Printf("Cannot stat '%s', error was: %s", link, err)
			return false, nil
		}
		if !linkfi.Mode().IsRegular() {
			jww.ERROR.Printf("Symbolic links for directories not supported, skipping '%s'", filePath)
		}
		return false, nil
	}

	if fi.IsDir() {
		if f.avoid(filePath) || isNonProcessablePath(filePath) {
			return false, filepath.SkipDir
		}
		return false, nil
	}

	if isNonProcessablePath(filePath) {
		return false, nil
	}
	return true, nil
}
예제 #2
1
func checkFile(f os.FileInfo) bool {
	if f.Mode().IsRegular() {
		return true
	}

	return false
}
예제 #3
0
func (self *Visitor) visit(path string, f os.FileInfo, err error) error {
	if f == nil {
		return err
	}
	if f.IsDir() {
		return nil
	} else if (f.Mode() & os.ModeSymlink) > 0 {
		return nil
	} else {
		if strings.HasSuffix(f.Name(), ".md") {
			fmt.Println(f)
			file, err := os.Open(f.Name())
			if err != nil {
				return err
			}
			input, _ := ioutil.ReadAll(file)
			input = regexp.MustCompile("\\[(.*?)\\]\\(<?(.*?)\\.md>?\\)").ReplaceAll(input, []byte("[$1](<$2.html>)"))
			var out *os.File
			if out, err = os.Create(strings.Replace(f.Name(), ".md", ".html", -1)); err != nil {
				fmt.Fprintf(os.Stderr, "Error creating %s: %v", f.Name(), err)
				os.Exit(-1)
			}
			defer out.Close()
			md := md2min.New("none")
			err = md.Parse(input, out)
			if err != nil {
				fmt.Fprintln(os.Stderr, "Parsing Error", err)
				os.Exit(-1)
			}
		}
	}
	return nil
}
예제 #4
0
// checkWalk is a helper function to sanity check for *.wsp files in a
// file tree walk.  If the file is valid, normal *.wsp nil is returned.
// Otherwise a non-nil error value is returned.
func checkWalk(path string, info os.FileInfo, err error) (bool, error) {
	// Did the Walk function hit an error on this file?
	if err != nil {
		log.Printf("%s\n", err)
		// File perm or exists error, log and skip
		return false, nil
	}

	// Sanity check our file
	if info.IsDir() {
		// Ignore dot-files and dot-directories
		if strings.HasPrefix(info.Name(), ".") {
			return false, filepath.SkipDir
		}
		return false, nil
	}
	if !info.Mode().IsRegular() {
		// Not a regular file
		return false, nil
	}
	if !strings.HasSuffix(path, ".wsp") {
		// Not a Whisper Database
		return false, nil
	}

	return true, nil
}
예제 #5
0
파일: flatfs.go 프로젝트: rht/bssim
func (fs *Datastore) enumerateKeys(fi os.FileInfo, res []query.Entry) ([]query.Entry, error) {
	if !fi.IsDir() || fi.Name()[0] == '.' {
		return res, nil
	}
	child, err := os.Open(path.Join(fs.path, fi.Name()))
	if err != nil {
		return nil, err
	}
	defer child.Close()
	objs, err := child.Readdir(0)
	if err != nil {
		return nil, err
	}
	for _, fi := range objs {
		if !fi.Mode().IsRegular() || fi.Name()[0] == '.' {
			return res, nil
		}
		key, ok := fs.decode(fi.Name())
		if !ok {
			return res, nil
		}
		res = append(res, query.Entry{Key: key.String()})
	}
	return res, nil
}
예제 #6
0
파일: tar.go 프로젝트: kcbabo/origin
// writeTarHeader writes tar header for given file, returns error if operation fails
func (t *stiTar) writeTarHeader(tarWriter *tar.Writer, dir string, path string, info os.FileInfo, includeDirInPath bool) error {
	var (
		link string
		err  error
	)
	if info.Mode()&os.ModeSymlink != 0 {
		link, err = os.Readlink(path)
		if err != nil {
			return err
		}
	}
	header, err := tar.FileInfoHeader(info, link)
	if err != nil {
		return err
	}
	prefix := dir
	if includeDirInPath {
		prefix = filepath.Dir(prefix)
	}
	header.Name = filepath.ToSlash(path[1+len(prefix):])
	glog.V(5).Infof("Adding to tar: %s as %s", path, header.Name)
	if err = tarWriter.WriteHeader(header); err != nil {
		return err
	}

	return nil
}
예제 #7
0
// Append the paths to an array in case that they are markdown files.
func (site *Site) parseAndStore(path string, fileInfo os.FileInfo, inputErr error) (err error) {
	if inputErr != nil {
		return inputErr
	}

	slugsPresence := make(map[string]bool)

	if !fileInfo.Mode().IsDir() && strings.HasSuffix(path, ".md") {
		file, err := file.New(path)
		if err != nil {
			return err
		}

		if _, present := slugsPresence[file.Slug]; present {
			return newUniqueSlugError(file.Slug)
		}
		slugsPresence[file.Slug] = true

		// Add the pages or articles to the proper array on the site
		if file.IsPage {
			site.Pages = append(site.Pages, file)
		} else {
			site.Articles = append(site.Articles, file)

			// Just supported on Articles
			if len(file.Tags) > 0 {
				site.AppendUniqueTags(file.Tags)
			}
			site.AppendUniqueCategory(file.Category)
		}
	}
	return
}
예제 #8
0
파일: ufs.go 프로젝트: KevinMGranger/go9p
func dir2Npmode(d os.FileInfo, dotu bool) uint32 {
	ret := uint32(d.Mode() & 0777)
	if d.IsDir() {
		ret |= p.DMDIR
	}

	if dotu {
		mode := d.Mode()
		if mode&os.ModeSymlink != 0 {
			ret |= p.DMSYMLINK
		}

		if mode&os.ModeSocket != 0 {
			ret |= p.DMSOCKET
		}

		if mode&os.ModeNamedPipe != 0 {
			ret |= p.DMNAMEDPIPE
		}

		if mode&os.ModeDevice != 0 {
			ret |= p.DMDEVICE
		}

		if mode&os.ModeSetuid != 0 {
			ret |= p.DMSETUID
		}

		if mode&os.ModeSetgid != 0 {
			ret |= p.DMSETGID
		}
	}

	return ret
}
예제 #9
0
파일: gcsfuse_test.go 프로젝트: zfo/gcsfuse
func (t *GcsfuseTest) FileAndDirModeFlags() {
	var err error
	var fi os.FileInfo

	// Mount with non-standard modes.
	args := []string{
		"--file-mode", "461",
		"--dir-mode", "511",
		canned.FakeBucketName,
		t.dir,
	}

	err = t.runGcsfuse(args)
	AssertEq(nil, err)
	defer unmount(t.dir)

	// Stat contents.
	fi, err = os.Lstat(path.Join(t.dir, canned.TopLevelFile))
	AssertEq(nil, err)
	ExpectEq(os.FileMode(0461), fi.Mode())

	fi, err = os.Lstat(path.Join(t.dir, canned.TopLevelDir))
	AssertEq(nil, err)
	ExpectEq(0511|os.ModeDir, fi.Mode())
}
예제 #10
0
파일: gcsfuse_test.go 프로젝트: zfo/gcsfuse
func (t *GcsfuseTest) CannedContents() {
	var err error
	var fi os.FileInfo

	// Mount.
	args := []string{canned.FakeBucketName, t.dir}

	err = t.runGcsfuse(args)
	AssertEq(nil, err)
	defer unmount(t.dir)

	// Check the expected contents of the file system.
	fi, err = os.Lstat(path.Join(t.dir, canned.TopLevelFile))
	AssertEq(nil, err)
	ExpectEq(os.FileMode(0644), fi.Mode())

	contents, err := ioutil.ReadFile(path.Join(t.dir, canned.TopLevelFile))
	AssertEq(nil, err)
	ExpectEq(canned.TopLevelFile_Contents, string(contents))

	fi, err = os.Lstat(path.Join(t.dir, canned.TopLevelDir))
	AssertEq(nil, err)
	ExpectEq(0755|os.ModeDir, fi.Mode())

	// The implicit directory shouldn't be visible, since we don't have implicit
	// directories enabled.
	_, err = os.Lstat(path.Join(t.dir, path.Dir(canned.ImplicitDirFile)))
	ExpectTrue(os.IsNotExist(err), "err: %v", err)
}
예제 #11
0
func list(path string, info os.FileInfo, node *fsNode, n *int) error {
	if (!info.IsDir() && !info.Mode().IsRegular()) || strings.HasPrefix(info.Name(), ".") {
		return errors.New("Non-regular file")
	}
	(*n)++
	if (*n) > fileNumberLimit {
		return errors.New("Over file limit") //limit number of files walked
	}
	node.Name = info.Name()
	node.Size = info.Size()
	node.Modified = info.ModTime()
	if !info.IsDir() {
		return nil
	}
	children, err := ioutil.ReadDir(path)
	if err != nil {
		return fmt.Errorf("Failed to list files")
	}
	node.Size = 0
	for _, i := range children {
		c := &fsNode{}
		p := filepath.Join(path, i.Name())
		if err := list(p, i, c, n); err != nil {
			continue
		}
		node.Size += c.Size
		node.Children = append(node.Children, c)
	}
	return nil
}
예제 #12
0
파일: fs.go 프로젝트: ranveerkunal/memfs
func (fs *memFileSystem) refreshCache(path string, info os.FileInfo) (err error) {
	// Delete the file if fi is nil.
	if info == nil {
		fs.lock.Lock()
		delete(fs.cache, path)
		fs.lock.Unlock()
		return
	}

	// Create memory fileinfo and read contents.
	fi := &memFileInfo{
		name:    info.Name(),
		size:    info.Size(),
		mode:    info.Mode(),
		modTime: info.ModTime(),
		isDir:   info.IsDir(),
		path:    path,
		fs:      fs,
	}

	// Fill content of the file from disk.
	if !fi.isDir {
		fi.content, err = ioutil.ReadFile(path)
		if err != nil {
			return
		}
	}

	// Update cache and return.
	fs.lock.Lock()
	fs.cache[path] = fi
	fs.lock.Unlock()
	return
}
예제 #13
0
파일: cache.go 프로젝트: wantedly/risu
func writeTarGz(filePath, baseDir string, tarGzWriter *tar.Writer, fileInfo os.FileInfo) error {
	file, err := os.Open(filePath)

	if err != nil {
		return err
	}
	defer file.Close()

	relativePath, err := filepath.Rel(baseDir, filePath)

	if err != nil {
		return err
	}

	header := new(tar.Header)
	header.Name = relativePath
	header.Size = fileInfo.Size()
	header.Mode = int64(fileInfo.Mode())
	header.ModTime = fileInfo.ModTime()

	err = tarGzWriter.WriteHeader(header)

	if err != nil {
		return err
	}

	_, err = io.Copy(tarGzWriter, file)

	if err != nil {
		return err
	}

	return nil
}
예제 #14
0
파일: ftp.go 프로젝트: r3nic1e/bbdownloader
func (ftp *FtpConnection) GetFile(local_path, remote_path string) error {
	var err error

	buf := new(bytes.Buffer)
	if err := ftp.Conn.Retrieve(remote_path, buf); err != nil {
		return err
	}

	var stat os.FileInfo
	stat, err = ftp.Stat(remote_path)
	if err != nil {
		return err
	}

	var file *os.File

	if file, err = os.OpenFile(local_path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, stat.Mode()); err != nil {
		return err
	}
	defer file.Close()

	file.Write(buf.Bytes())

	return nil
}
예제 #15
0
func update(p string, f os.FileInfo, err error) error {
	// Check the file mode.
	if f.IsDir() {
		m := os.FileMode(*cliChmodDir)
		if f.Mode().Perm() != m.Perm() {
			err := os.Chmod(p, m)
			if err != nil {
				log.Printf("Failed to chmod directory: %s", p)
			}
			log.Printf("Updated chmod directory: %s", p)
		}
	} else {
		m := os.FileMode(*cliChmodFile)
		if f.Mode().Perm() != m.Perm() {
			err := os.Chmod(p, m)
			if err != nil {
				log.Printf("Failed to chmod file: %s", p)
			}
			log.Printf("Updated chmod file: %s", p)
		}
	}

	// Check the file owner.
	fu := f.Sys().(*syscall.Stat_t).Uid
	fg := f.Sys().(*syscall.Stat_t).Gid
	if int(fu) != uid && int(fg) != gid {
		err := os.Chown(p, uid, gid)
		if err != nil {
			log.Printf("Failed to chown file: %s", p)
		}
		log.Printf("Updated chown file: %s", p)
	}

	return nil
}
예제 #16
0
파일: pack.go 프로젝트: Linvas/ant
func (wft *walkFileTree) walkLeaf(fpath string, fi os.FileInfo, err error) error {
	if err != nil {
		return err
	}

	if fpath == outputP {
		return nil
	}

	if fi.IsDir() {
		return nil
	}

	if ssym && fi.Mode()&os.ModeSymlink > 0 {
		return nil
	}

	name := wft.virPath(fpath)

	if wft.allfiles[name] {
		return nil
	}

	if added, err := wft.wak.compress(name, fpath, fi); added {
		if verbose {
			fmt.Printf("Compressed: %s\n", name)
		}
		wft.allfiles[name] = true
		return err
	} else {
		return err
	}
}
예제 #17
0
파일: pack.go 프로젝트: Linvas/ant
func (wft *tarWalk) compress(name, fpath string, fi os.FileInfo) (bool, error) {
	isSym := fi.Mode()&os.ModeSymlink > 0
	link := ""
	if isSym {
		link, _ = os.Readlink(fpath)
	}

	hdr, err := tar.FileInfoHeader(fi, link)
	if err != nil {
		return false, err
	}
	hdr.Name = name

	tw := wft.tw
	err = tw.WriteHeader(hdr)
	if err != nil {
		return false, err
	}

	if isSym == false {
		fr, err := os.Open(fpath)
		if err != nil {
			return false, err
		}
		defer fr.Close()
		_, err = io.Copy(tw, fr)
		if err != nil {
			return false, err
		}
		tw.Flush()
	}

	return true, nil
}
예제 #18
0
파일: walk.go 프로젝트: nrm21/syncthing
func (w *walker) walkDir(relPath string, info os.FileInfo, dchan chan protocol.FileInfo) error {
	// A directory is "unchanged", if it
	//  - exists
	//  - has the same permissions as previously, unless we are ignoring permissions
	//  - was not marked deleted (since it apparently exists now)
	//  - was a directory previously (not a file or something else)
	//  - was not a symlink (since it's a directory now)
	//  - was not invalid (since it looks valid now)
	cf, ok := w.CurrentFiler.CurrentFile(relPath)
	permUnchanged := w.IgnorePerms || !cf.HasPermissionBits() || PermsEqual(cf.Permissions, uint32(info.Mode()))
	if ok && permUnchanged && !cf.IsDeleted() && cf.IsDirectory() && !cf.IsSymlink() && !cf.IsInvalid() {
		return nil
	}

	f := protocol.FileInfo{
		Name:          relPath,
		Type:          protocol.FileInfoTypeDirectory,
		Version:       cf.Version.Update(w.ShortID),
		Permissions:   uint32(info.Mode() & maskModePerm),
		NoPermissions: w.IgnorePerms,
		ModifiedS:     info.ModTime().Unix(),
		ModifiedNs:    int32(info.ModTime().Nanosecond()),
		ModifiedBy:    w.ShortID,
	}
	l.Debugln("dir:", relPath, f)

	select {
	case dchan <- f:
	case <-w.Cancel:
		return errors.New("cancelled")
	}

	return nil
}
예제 #19
0
파일: ufs.go 프로젝트: KevinMGranger/go9p
func (dir *Dir) dotu(path string, d os.FileInfo, upool p.Users, sysMode *syscall.Stat_t) {
	u := upool.Uid2User(int(sysMode.Uid))
	g := upool.Gid2Group(int(sysMode.Gid))
	dir.Uid = u.Name()
	if dir.Uid == "" {
		dir.Uid = "none"
	}

	dir.Gid = g.Name()
	if dir.Gid == "" {
		dir.Gid = "none"
	}
	dir.Muid = "none"
	dir.Ext = ""
	dir.Uidnum = uint32(u.Id())
	dir.Gidnum = uint32(g.Id())
	dir.Muidnum = p.NOUID
	if d.Mode()&os.ModeSymlink != 0 {
		var err error
		dir.Ext, err = os.Readlink(path)
		if err != nil {
			dir.Ext = ""
		}
	} else if isBlock(d) {
		dir.Ext = fmt.Sprintf("b %d %d", sysMode.Rdev>>24, sysMode.Rdev&0xFFFFFF)
	} else if isChar(d) {
		dir.Ext = fmt.Sprintf("c %d %d", sysMode.Rdev>>24, sysMode.Rdev&0xFFFFFF)
	}
}
예제 #20
0
// Prints the filesystem to stdout, useful for testing.
// Not part of the filesystem interface.
func (mf *MockFilesystem) Print() {
	var (
		dirs   []string
		lines  [][]interface{}
		path   string
		f      File
		fi     os.FileInfo
		files  []os.FileInfo
		maxlen int
	)
	dirs = append(dirs, "/")
	maxlen = 1
	for len(dirs) > 0 {
		path = dirs[0]
		dirs = dirs[1:]
		f, _ = mf.Open(path)
		fi, _ = f.Stat()
		files, _ = f.Readdir(100)
		for _, fi = range files {
			name := filepath.Join(path, fi.Name())
			line := []interface{}{name, fi.Mode(), fi.IsDir()}
			lines = append(lines, line)
			if len(name) > maxlen {
				maxlen = len(name)
			}
			if fi.IsDir() {
				dirs = append(dirs, name)
			}
		}
	}
	fmtstr := fmt.Sprintf("%%-%vv %%v %%v\n", maxlen)
	for _, line := range lines {
		fmt.Printf(fmtstr, line[0], line[1], line[2])
	}
}
예제 #21
0
파일: archive.go 프로젝트: jquag/kempt
func archiveFile(fname string, cfg *conf.Config, rootStat os.FileInfo, fs os.FileInfo) (newname string, err error) {
	year := strconv.Itoa(fs.ModTime().Year())
	month := fs.ModTime().Month().String()

	archivePath := filepath.Join(cfg.ArchivePath(rootStat.Name()), year, month)
	err = os.MkdirAll(archivePath, rootStat.Mode())
	if err != nil && !os.IsExist(err) {
		return
	}

	zipPath := archivePath + ".zip"
	if util.FileExists(zipPath) {
		//unzip so we can archive the new file ... it will be rezipped later
		if err = util.Unzip(zipPath, archivePath); err != nil {
			return
		}
	}

	newname = filepath.Join(archivePath, fs.Name())
	if _, err = os.Stat(newname); err == nil {
		err = fmt.Errorf("A file of the same name already exists in the archive")
		return
	}
	err = os.Rename(fname, newname)

	return
}
예제 #22
0
// Write a single file to TarGz
func TarGzWrite(item ArchiveItem, tw *tar.Writer, fi os.FileInfo) (err error) {
	if item.FileSystemPath != "" {
		fr, err := os.Open(item.FileSystemPath)
		if err == nil {
			defer fr.Close()

			h := new(tar.Header)
			h.Name = item.ArchivePath
			h.Size = fi.Size()
			h.Mode = int64(fi.Mode())
			h.ModTime = fi.ModTime()

			err = tw.WriteHeader(h)

			if err == nil {
				_, err = io.Copy(tw, fr)
			}
		}
	} else {
		h := new(tar.Header)
		//backslash-only paths
		h.Name = strings.Replace(item.ArchivePath, "\\", "/", -1)
		h.Size = int64(len(item.Data))
		h.Mode = int64(0644) //? is this ok?
		h.ModTime = time.Now()
		err = tw.WriteHeader(h)
		if err == nil {
			_, err = tw.Write(item.Data)
		}
	}
	return err
}
예제 #23
0
func checkDir(f os.FileInfo) bool {
	if f.Mode().IsDir() {
		return true
	}

	return false
}
예제 #24
0
파일: hash.go 프로젝트: mildred/doc
// Return the hash for path stored in the xattrs. If the hash is out of date,
// the hash is computed anew, unless `compute` is false in which case nil is
// returned.
func GetHash(path string, info os.FileInfo, compute bool) (mh.Multihash, error) {
	if info.Mode()&os.ModeSymlink != 0 {
		return symlinkHash(path)
	}

	hashTimeStr, err := attrs.Get(path, XattrHashTime)
	if err != nil {
		if compute {
			return HashFile(path, info)
		} else if IsNoData(err) {
			// ignore error
			return nil, nil
		} else {
			return nil, err
		}
	}

	hashTime, err := time.Parse(time.RFC3339Nano, string(hashTimeStr))
	if err != nil {
		return nil, err
	}

	if hashTime != info.ModTime() {
		if compute {
			return HashFile(path, info)
		} else {
			return nil, nil
		}
	}

	return attrs.Get(path, XattrHash)
}
예제 #25
0
func checkCopyright(path string, info os.FileInfo, err error) error {
	if err != nil {
		return err
	}
	if !info.Mode().IsRegular() {
		return nil
	}
	if !checkExts[filepath.Ext(path)] {
		return nil
	}

	fd, err := os.Open(path)
	if err != nil {
		return err
	}
	defer fd.Close()

	scanner := bufio.NewScanner(fd)
	for i := 0; scanner.Scan() && i < 5; i++ {
		if copyrightRe.MatchString(scanner.Text()) {
			return nil
		}
	}

	return fmt.Errorf("Missing copyright in %s?", path)
}
예제 #26
0
func isRegularFile(fi os.FileInfo) bool {
	if fi == nil {
		return false
	}

	return fi.Mode()&(os.ModeType|os.ModeCharDevice) == 0
}
예제 #27
0
func NewSerialFile(name, path string, hidden bool, stat os.FileInfo) (File, error) {
	switch mode := stat.Mode(); {
	case mode.IsRegular():
		file, err := os.Open(path)
		if err != nil {
			return nil, err
		}
		return NewReaderFile(name, path, file, stat), nil
	case mode.IsDir():
		// for directories, stat all of the contents first, so we know what files to
		// open when NextFile() is called
		contents, err := ioutil.ReadDir(path)
		if err != nil {
			return nil, err
		}
		return &serialFile{name, path, contents, stat, nil, hidden}, nil
	case mode&os.ModeSymlink != 0:
		target, err := os.Readlink(path)
		if err != nil {
			return nil, err
		}
		return NewLinkFile(name, path, target, stat), nil
	default:
		return nil, fmt.Errorf("Unrecognized file type for %s: %s", name, mode.String())
	}
}
예제 #28
0
파일: mdi.go 프로젝트: sogyf/Story-Figures
func (self *F) visit(path string, f os.FileInfo, err error) error {
	if f == nil {
		return err
	}
	//如果是txt文本
	if strings.HasSuffix(f.Name(), "txt") {
		var tp int
		if f.IsDir() {
			tp = IsDirectory
		} else if (f.Mode() & os.ModeSymlink) > 0 {
			tp = IsSymlink
		} else {
			tp = IsRegular
		}
		inoFile := &sysFile{
			fName:      path,
			fType:      tp,
			fPerm:      f.Mode(),
			fMtime:     f.ModTime(),
			fSize:      f.Size(),
			fShortName: f.Name(),
		}
		self.files = append(self.files, inoFile)
	}
	return nil
}
예제 #29
0
func (t *tarmonster) walk(path string, info os.FileInfo, err error) error {
	if err != nil {
		return err
	}

	if !info.Mode().IsRegular() || info.Size() == 0 {
		return nil
	}

	file, err := os.Open(path)
	if err != nil {
		return err
	}
	defer file.Close()

	// Get tar.Header
	fih, err := tar.FileInfoHeader(info, "")
	if err != nil {
		return err
	}
	fih.Name = strings.TrimPrefix(path, t.src+string(filepath.Separator))

	// Begin a new file
	if err := t.writer.WriteHeader(fih); err != nil {
		return err
	}

	// Write the file
	if _, err := io.CopyBuffer(t.writer, file, t.buffer); err != nil {
		return err
	}

	return err
}
예제 #30
0
파일: main.go 프로젝트: npat-efault/bundle
func isYounger(ofn string, ifn string) bool {
	var oinf os.FileInfo
	var err error

	if ofn == "" {
		return false
	}
	oinf, err = os.Stat(ofn)
	if err != nil || !oinf.Mode().IsRegular() {
		return false
	}

	var wf = func(p string, iinf os.FileInfo, e error) error {
		if e != nil {
			return e
		}
		if !oinf.ModTime().After(iinf.ModTime()) {
			err := errors.New("this is younger")
			return err
		}
		return nil
	}
	err = filepath.Walk(ifn, wf)
	if err != nil {
		return false
	}
	return true
}