// TraversesSymlink returns an error if any path component of name (including name
// itself) traverses a symlink.
553731
func TraversesSymlink(filesystem fs.Filesystem, name string) error {
	var err error
	name, err = fs.Canonicalize(name)
	if err != nil {
		return err
	}

	if name == "." {
		// The result of calling TraversesSymlink(filesystem, filepath.Dir("foo"))
		return nil
	}

	var path string
	for _, part := range strings.Split(name, string(fs.PathSeparator)) {
		path = filepath.Join(path, part)
		info, err := filesystem.Lstat(path)
		if err != nil {
			if fs.IsNotExist(err) {
				return nil
			}
			return err
		}
		if info.IsSymlink() {
			return &TraversesSymlinkError{
				path: path,
			}
		}
		if !info.IsDir() {
			return &NotADirectoryError{
				path: path,
			}
		}
	}
	return nil
}
579686
func Symlink(oldname, newname string) error {
	if err := os.Symlink(oldname, newname); err != nil {
		// Ignore already created symlink
		if _, ok := err.(*os.LinkError); !ok {
			return err
		}
	}
	return nil
}
808644
func EnsureSymlinks(jujuDir, dir string, commands []string) (err error) {
	logger.Infof("ensure jujuc symlinks in %s", dir)
	defer func() {
		if err != nil {
			err = errors.Annotatef(err, "cannot initialize commands in %q", dir)
		}
	}()
	isSymlink, err := symlink.IsSymlink(jujuDir)
	if err != nil {
		return err
	}
	if isSymlink {
		link, err := symlink.Read(jujuDir)
		if err != nil {
			return err
		}
		if !filepath.IsAbs(link) {
			logger.Infof("%s is relative", link)
			link = filepath.Join(filepath.Dir(dir), link)
		}
		jujuDir = link
		logger.Infof("was a symlink, now looking at %s", jujuDir)
	}

	jujudPath := filepath.Join(jujuDir, names.Jujud)
	logger.Debugf("jujud path %s", jujudPath)
	for _, name := range commands {
		// The link operation fails when the target already exists,
		// so this is a no-op when the command names already
		// exist.
		err := symlink.New(jujudPath, filepath.Join(dir, name))
		if err != nil && !os.IsExist(err) {
			return err
		}
	}
	return nil
}
374918
func (b *Browser) Symlink(_, _ string) (err error) {
	return errors.New("browser cannot make symlinks")
}
845605
func (w *Writer) Link(oldname, newname string) error {
	if err := w.finishInode(); err != nil {
		return err
	}
	newdir, existing, newchildname, err := w.lookup(newname, false)
	if err != nil {
		return err
	}
	if existing != nil && (existing.IsDir() || existing.LinkCount < 2) {
		return fmt.Errorf("%s: cannot orphan existing file or directory", newname)
	}

	_, oldfile, _, err := w.lookup(oldname, true)
	if err != nil {
		return err
	}
	switch oldfile.Mode & format.TypeMask {
	case format.S_IFDIR, format.S_IFLNK:
		return fmt.Errorf("%s: link target cannot be a directory or symlink: %s", newname, oldname)
	}

	if existing != oldfile && oldfile.LinkCount >= format.MaxLinks {
		return fmt.Errorf("%s: link target would exceed maximum link count: %s", newname, oldname)
	}

	if existing != nil {
		existing.LinkCount--
	}
	oldfile.LinkCount++
	newdir.Children[newchildname] = oldfile
	return nil
}
646471
func VtctldLink(text, urlPath string) template.HTML {
	if *vtctldAddr == "" {
		return template.HTML(text)
	}
	var fullURL string
	if strings.HasSuffix(*vtctldAddr, "/") {
		fullURL = *vtctldAddr + urlPath
	} else {
		fullURL = *vtctldAddr + "/" + urlPath
	}

	return template.HTML(fmt.Sprintf(`<a href="%v">%v</a>`, fullURL, text))
}
537907
func (h *fs) Readlink(name string) (string, error) {
	return os.Readlink(name)
}
532080
func (m *Mapper) TraversalsByNameFunc(t reflect.Type, names []string, fn func(int, []int) error) error {
	t = Deref(t)
	mustBe(t, reflect.Struct)
	tm := m.TypeMap(t)
	for i, name := range names {
		fi, ok := tm.Names[name]
		if !ok {
			if err := fn(i, nil); err != nil {
				return err
			}
		} else {
			if err := fn(i, fi.Index); err != nil {
				return err
			}
		}
	}
	return nil
}
845108
func (n *mutDir) Symlink(ctx context.Context, req *fuse.SymlinkRequest) (fs.Node, error) {
	node, err := n.creat(ctx, req.NewName, symlinkType)
	if err != nil {
		Logger.Printf("mutDir.Symlink(%q): %v", req.NewName, err)
		return nil, fuse.EIO
	}
	mf := node.(*mutFile)
	mf.symLink = true
	mf.target = req.Target

	claim := schema.NewSetAttributeClaim(mf.permanode, "camliSymlinkTarget", req.Target)
	_, err = n.fs.client.UploadAndSignBlob(ctx, claim)
	if err != nil {
		Logger.Printf("mutDir.Symlink(%q) upload error: %v", req.NewName, err)
		return nil, fuse.EIO
	}

	return node, nil
}
64830
func (RealOS) Symlink(oldname string, newname string) error {
	return os.Symlink(oldname, newname)
}
158558
func (h *Handle) LinkByName(name string) (Link, error) {
	if h.lookupByDump {
		return h.linkByNameDump(name)
	}

	req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK)

	msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
	req.AddData(msg)

	attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF))
	req.AddData(attr)

	nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(name))
	req.AddData(nameData)

	link, err := execGetLink(req)
	if err == unix.EINVAL {
		// older kernels don't support looking up via IFLA_IFNAME
		// so fall back to dumping all links
		h.lookupByDump = true
		return h.linkByNameDump(name)
	}

	return link, err
}
984754
func FollowSymlinkInScope(path, root string) (string, error) {
	path, err := filepath.Abs(filepath.FromSlash(path))
	if err != nil {
		return "", err
	}
	root, err = filepath.Abs(filepath.FromSlash(root))
	if err != nil {
		return "", err
	}
	return evalSymlinksInScope(path, root)
}
545378
func (ut *UploadTracker) populateSymlinks(symlinks []*Item) error {
	for _, item := range symlinks {
		l, err := ut.lOS.Readlink(item.Path)
		if err != nil {
			return fmt.Errorf("unable to resolve symlink for %q: %v", item.Path, err)
		}
		ut.isol.Files[item.RelPath] = isolated.SymLink(l)
	}
	return nil
}
1279843
func getSymlinkedAssets(path string) ([]string, error) {
	assets := []string{}
	maxLevels := 100
	levels := maxLevels
	for {
		if levels < 1 {
			return nil, fmt.Errorf("Too many levels of symlinks (>$d)", maxLevels)
		}
		fi, err := os.Lstat(path)
		if err != nil {
			return nil, err
		}
		asset := getAssetString(path, path)
		assets = append(assets, asset)
		if !isSymlink(fi.Mode()) {
			break
		}
		symTarget, err := os.Readlink(path)
		if err != nil {
			return nil, err
		}
		if filepath.IsAbs(symTarget) {
			path = symTarget
		} else {
			path = filepath.Join(filepath.Dir(path), symTarget)
		}
		levels--
	}
	return assets, nil
}
745206
func (this *MarkupAsciiDoc) link(anchorName, linkText string) string {
	if linkText == "" {
		return fmt.Sprintf("<<%s,%s>>", anchorName, anchorName)
	}
	return fmt.Sprintf("<<%s,%s>>", anchorName, linkText)
}
409958
func (mounter *Mounter) EvalHostSymlinks(pathname string) (string, error) {
	return filepath.EvalSymlinks(pathname)
}
666795
func copySymLink(src, dst string) (err error) {
	link, err := os.Readlink(src)
	if err != nil {
		return err
	}

	return os.Symlink(link, dst)
}