Beispiel #1
0
// Symlink creates a symbolic link.
func Symlink(oldname, newname string) Error {
	e := syscall.Symlink(oldname, newname)
	if e != 0 {
		return &LinkError{"symlink", oldname, newname, Errno(e)}
	}
	return nil
}
Beispiel #2
0
// Symlink creates newname as a symbolic link to oldname.
// If there is an error, it will be of type *LinkError.
func Symlink(oldname, newname string) error {
	e := syscall.Symlink(oldname, newname)
	if e != nil {
		return &LinkError{"symlink", oldname, newname, e}
	}
	return nil
}
Beispiel #3
0
func (constor *Constor) Symlink(header *fuse.InHeader, pointedTo string, linkName string, out *fuse.EntryOut) (code fuse.Status) {
	inode := constor.inodemap.findInodePtr(header.NodeId)
	if inode == nil {
		constor.error("inode == nil")
		return fuse.ENOENT
	}
	err := constor.copyup(inode)
	if err != nil {
		constor.error("copyup failed for %s - %s", inode.id, err)
		return fuse.ToStatus(err)
	}
	dirpath := constor.getPath(0, inode.id)
	entrypath := Path.Join(dirpath, linkName)

	constor.log("%s <- %s/%s", pointedTo, inode.id, linkName)
	syscall.Unlink(entrypath) // remove a deleted entry
	err = syscall.Symlink(pointedTo, entrypath)
	if err != nil {
		constor.error("Symlink failed %s <- %s : %s", pointedTo, entrypath, err)
		return fuse.ToStatus(err)
	}
	id := constor.setid(entrypath, "")
	if id == "" {
		constor.error("setid failed on %s", entrypath)
		return fuse.ENOENT
	}
	if err := constor.createPath(id); err != nil {
		constor.error("createPath failed on %s : %s", id, err)
		return fuse.ToStatus(err)
	}
	path := constor.getPath(0, id)
	err = syscall.Symlink(pointedTo, path)
	if err != nil {
		constor.error("Symlink failed %s <- %s : %s", pointedTo, path, err)
		return fuse.ToStatus(err)
	}
	err = syscall.Lchown(path, int(header.Uid), int(header.Gid))
	if err != nil {
		constor.error("Chown failed on %s : %s", path, err)
		return fuse.ToStatus(err)
	}
	return constor.Lookup(header, linkName, out)
}
Beispiel #4
0
// Symlink implements pathfs.Filesystem.
func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (code fuse.Status) {
	tlog.Debug.Printf("Symlink(\"%s\", \"%s\")", target, linkName)
	if fs.isFiltered(linkName) {
		return fuse.EPERM
	}
	cPath, err := fs.getBackingPath(linkName)
	if err != nil {
		return fuse.ToStatus(err)
	}
	if fs.args.PlaintextNames {
		err = os.Symlink(target, cPath)
		return fuse.ToStatus(err)
	}
	// Symlinks are encrypted like file contents (GCM) and base64-encoded
	cBinTarget := fs.contentEnc.EncryptBlock([]byte(target), 0, nil)
	cTarget := base64.URLEncoding.EncodeToString(cBinTarget)
	// Handle long file name
	cName := filepath.Base(cPath)
	if nametransform.IsLongContent(cName) {
		var dirfd *os.File
		dirfd, err = os.Open(filepath.Dir(cPath))
		if err != nil {
			return fuse.ToStatus(err)
		}
		defer dirfd.Close()
		// Create ".name" file
		err = fs.nameTransform.WriteLongName(dirfd, cName, linkName)
		if err != nil {
			return fuse.ToStatus(err)
		}
		// Create "gocryptfs.longfile." symlink
		// TODO use syscall.Symlinkat once it is available in Go
		err = syscall.Symlink(cTarget, cPath)
		if err != nil {
			nametransform.DeleteLongName(dirfd, cName)
		}
	} else {
		// Create symlink
		err = os.Symlink(cTarget, cPath)
	}
	if err != nil {
		return fuse.ToStatus(err)
	}
	// Set owner
	if fs.args.PreserveOwner {
		err = os.Lchown(cPath, int(context.Owner.Uid), int(context.Owner.Gid))
		if err != nil {
			tlog.Warn.Printf("Mknod: Lchown failed: %v", err)
		}
	}
	return fuse.OK
}
Beispiel #5
0
// Returns true if there were any operations performed
func updateDisk(files_to_add filesOfCatalog,
	files_to_remove filesOfCatalog,
	catalog_root string) bool {
	changes_made := false

	for catspec, files_by_path := range files_to_add {
		for path, link := range files_by_path {
			tgt_path := filepath.Join(catalog_root, catspec.Catrel, catspec.Arch,
				shortenOsrel(catspec.Osrel), path)
			if link.link_type == hardlink {
				src_path := filepath.Join(catalog_root, "allpkgs", path)
				if !DryRun {
					if err := syscall.Link(src_path, tgt_path); err != nil {
						log.Fatalf("Could not create hardlink from %v to %v: %v",
							src_path, tgt_path, err)
					}
				}
				log.Printf("ln \"%s\"\n   \"%s\"\n", src_path, tgt_path)
				changes_made = true
			} else if link.link_type == symlink {
				// The source path is relative to the target, because it's a symlink
				src_path := *(link.target)
				if !DryRun {
					if err := syscall.Symlink(src_path, tgt_path); err != nil {
						log.Fatalf("Could not symlink %v to %v: %v", src_path, tgt_path, err)
					}
				}
				log.Printf("ln -s \"%s\"\n  \"%s\"\n", src_path, tgt_path)
				changes_made = true
			} else {
				log.Fatalln("Zonk! Wrong link type in %+v", link)
			}
		}
	}

	for catspec, files_by_path := range files_to_remove {
		for path, _ := range files_by_path {
			pkg_path := filepath.Join(catalog_root, catspec.Catrel, catspec.Arch,
				shortenOsrel(catspec.Osrel), path)
			if !DryRun {
				if err := syscall.Unlink(pkg_path); err != nil {
					log.Fatalf("Could not unlink %v: %v", pkg_path, err)
				}
			}
			log.Printf("rm \"%s\"\n", pkg_path)
			changes_made = true
		}
	}
	return changes_made
}
Beispiel #6
0
func (constor *Constor) Symlink(header *fuse.InHeader, pointedTo string, linkName string, out *fuse.EntryOut) (code fuse.Status) {
	constor.log("%d %s <- %s, uid: %d, gid: %d", header.NodeId, pointedTo, linkName, header.Uid, header.Gid)
	parentino := header.NodeId
	path, err := constor.dentrymap.getPath(parentino)
	if err != nil {
		return fuse.ToStatus(err)
	}
	if err = constor.createPath(path); err != nil {
		return fuse.ToStatus(err)
	}
	pathl := Path.Join(constor.layers[0], path, linkName)
	syscall.Unlink(pathl) // remove a deleted entry
	err = syscall.Symlink(pointedTo, pathl)
	if err != nil {
		return fuse.ToStatus(err)
	}
	err = syscall.Lchown(pathl, int(header.Uid), int(header.Gid))
	if err != nil {
		return fuse.ToStatus(err)
	}
	return constor.Lookup(header, linkName, out)
}
Beispiel #7
0
Datei: fs.go Projekt: drptbl/oz
func (fs *Filesystem) CreateSymlink(oldpath, newpath string) error {
	if err := syscall.Symlink(oldpath, fs.absPath(newpath)); err != nil {
		return fmt.Errorf("failed to symlink %s to %s: %v", fs.absPath(newpath), oldpath, err)
	}
	return nil
}
Beispiel #8
0
func (s syscallImpl) Symlink(oldname, newname string) error {
	return syscall.Symlink(oldname, newname)
}
Beispiel #9
0
func (k *PosixKernel) Symlink(src, dst string) uint64 {
	return Errno(syscall.Symlink(src, dst))
}
Beispiel #10
0
func ln(target, source string, isdir bool) error {
	var fi os.FileInfo
	var err error

	statp := os.Stat
	if Pflag {
		statp = os.Lstat
	}
	if !sflag {
		fi, err = statp(target)
		if err != nil {
			return err
		}

		// only symbolic links to directory
		if fi.IsDir() {
			return fmt.Errorf("%s is a directory", target)
		}
	}

	// if the source is a directory, append the target's name
	statl := os.Stat
	if hflag {
		statl = os.Lstat
	}
	if isdir {
		fi, err = statl(source)
		if err == nil && fi.IsDir() {
			base := filepath.Base(target)
			if base == "" {
				return fmt.Errorf("%s", target)
			}
			source = filepath.Join(source, base)
		}
	}

	fi, err = os.Lstat(source)
	if err == nil && !sflag {
		tfi, err := statp(target)
		if err != nil {
			return fmt.Errorf("%s: dissapeared", target)
		}

		st, ok1 := fi.Sys().(*syscall.Stat_t)
		sb, ok2 := tfi.Sys().(*syscall.Stat_t)
		if ok1 && ok2 && st.Dev == sb.Dev && st.Ino == sb.Ino {
			if fflag {
				return nil
			} else {
				return fmt.Errorf("%s and %s are identical (nothing done).", target, source)
			}
		}
	}

	if fflag {
		err = syscall.Unlink(source)
	} else if sflag {
		err = syscall.Symlink(target, source)
	} else {
		follow := 0
		if !Pflag {
			follow = unix.AT_SYMLINK_FOLLOW
		}
		err = unix.Linkat(unix.AT_FDCWD, target, unix.AT_FDCWD, source, follow)
	}
	return err
}
Beispiel #11
0
Datei: main.go Projekt: drptbl/oz
func handleInstall(c *cli.Context) {
	OzConfig = loadConfig()
	pname := c.Args()[0]
	OzProfile, err := loadProfile(pname, OzConfig.ProfileDir)
	if err != nil || OzProfile == nil {
		installExit(c.Bool("hook"), fmt.Errorf("Unable to load profiles for %s (%v).\n", pname, err))
		return // For clarity
	}

	if OzConfig.DivertSuffix == "" {
		installExit(c.Bool("hook"), fmt.Errorf("Divert requires a suffix to be set.\n"))
		return // For clarity
	}

	divertInstall := func(cpath string) {
		isInstalled, err := isDivertInstalled(cpath)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Unknown error: %+v\n", err)
			os.Exit(1)
		}
		if isInstalled == true {
			fmt.Println("Divert already installed for ", cpath)
			if c.Bool("force") {
				return
			}
			os.Exit(0)
		}

		dpkgArgs := []string{
			"--add",
			"--package",
			"oz",
			"--rename",
			"--divert",
			getBinaryPath(cpath),
			cpath,
		}

		_, err = exec.Command(PathDpkgDivert, dpkgArgs...).Output()
		if err != nil {
			fmt.Fprintf(os.Stderr, "Dpkg divert command `%s %+s` failed: %s", PathDpkgDivert, dpkgArgs, err)
			os.Exit(1)
		}

		clientbin := path.Join(OzConfig.PrefixPath, "bin", "oz")
		err = syscall.Symlink(clientbin, cpath)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to create symlink %s", err)
			os.Exit(1)
		}

		fmt.Printf("Successfully installed Oz sandbox for: %s.\n", cpath)
	}

	paths := append([]string{}, OzProfile.Path)
	paths = append(paths, OzProfile.Paths...)
	for _, pp := range paths {
		divertInstall(pp)
	}

	fmt.Printf("Successfully installed Oz sandbox for: %s.\n", OzProfile.Name)
}