<commit_before>// +build linux
// +build cgo

package idmap

import (
	"fmt"
	"unsafe"

	"github.com/lxc/lxd/shared"
)

// #cgo LDFLAGS: -lacl
/*
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/capability.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/acl.h>

// Needs to be included at the end
#include <attr/xattr.h>

#ifndef VFS_CAP_REVISION_1
#define VFS_CAP_REVISION_1 0x01000000
#endif

#ifndef VFS_CAP_REVISION_2
#define VFS_CAP_REVISION_2 0x02000000
#endif

#ifndef VFS_CAP_REVISION_3
#define VFS_CAP_REVISION_3 0x03000000
struct vfs_ns_cap_data {
	__le32 magic_etc;
	struct {
		__le32 permitted;
		__le32 inheritable;
	} data[VFS_CAP_U32];
	__le32 rootid;
};
#endif


int set_vfs_ns_caps(char *path, char *caps, ssize_t len, uint32_t uid)
{
	// Works because vfs_ns_cap_data is a superset of vfs_cap_data (rootid
	// field added to the end)
	struct vfs_ns_cap_data ns_xattr;

	memset(&ns_xattr, 0, sizeof(ns_xattr));
	memcpy(&ns_xattr, caps, len);
	ns_xattr.magic_etc &= ~(VFS_CAP_REVISION_1 | VFS_CAP_REVISION_2);
	ns_xattr.magic_etc |= VFS_CAP_REVISION_3;
	ns_xattr.rootid = uid;

	return setxattr(path, "security.capability", &ns_xattr, sizeof(ns_xattr), 0);
}

int shiftowner(char *basepath, char *path, int uid, int gid)
{
	int fd, ret;
	char fdpath[PATH_MAX], realpath[PATH_MAX];
	struct stat sb;

	fd = open(path, O_PATH | O_NOFOLLOW);
	if (fd < 0) {
		perror("Failed open");
		return 1;
	}

	ret = sprintf(fdpath, "/proc/self/fd/%d", fd);
	if (ret < 0) {
		perror("Failed sprintf");
		close(fd);
		return 1;
	}<commit_msg>idmap: convert uid from big to little endian<commit_after>// +build linux
// +build cgo

package idmap

import (
	"fmt"
	"unsafe"

	"github.com/lxc/lxd/shared"
)

// #cgo LDFLAGS: -lacl
/*
#define _GNU_SOURCE
#include <byteswap.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/capability.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/acl.h>

// Needs to be included at the end
#include <attr/xattr.h>

#ifndef VFS_CAP_REVISION_1
#define VFS_CAP_REVISION_1 0x01000000
#endif

#ifndef VFS_CAP_REVISION_2
#define VFS_CAP_REVISION_2 0x02000000
#endif

#ifndef VFS_CAP_REVISION_3
#define VFS_CAP_REVISION_3 0x03000000
struct vfs_ns_cap_data {
	__le32 magic_etc;
	struct {
		__le32 permitted;
		__le32 inheritable;
	} data[VFS_CAP_U32];
	__le32 rootid;
};
#endif

#if __BYTE_ORDER == __BIG_ENDIAN
#define BE32_TO_LE32(x) bswap_32(x)
#else
#define BE32_TO_LE32(x) (x)
#endif

int set_vfs_ns_caps(char *path, char *caps, ssize_t len, uint32_t uid)
{
	// Works because vfs_ns_cap_data is a superset of vfs_cap_data (rootid
	// field added to the end)
	struct vfs_ns_cap_data ns_xattr;

	memset(&ns_xattr, 0, sizeof(ns_xattr));
	memcpy(&ns_xattr, caps, len);
	ns_xattr.magic_etc &= ~(VFS_CAP_REVISION_1 | VFS_CAP_REVISION_2);
	ns_xattr.magic_etc |= VFS_CAP_REVISION_3;
	ns_xattr.rootid = BE32_TO_LE32(uid);

	return setxattr(path, "security.capability", &ns_xattr, sizeof(ns_xattr), 0);
}

int shiftowner(char *basepath, char *path, int uid, int gid)
{
	int fd, ret;
	char fdpath[PATH_MAX], realpath[PATH_MAX];
	struct stat sb;

	fd = open(path, O_PATH | O_NOFOLLOW);
	if (fd < 0) {
		perror("Failed open");
		return 1;
	}

	ret = sprintf(fdpath, "/proc/self/fd/%d", fd);
	if (ret < 0) {
		perror("Failed sprintf");
		close(fd);
		return 1;
	}
{'fraction_non_alphanumeric': 0.13310676862078732, 'fraction_numerical': 0.034551118663268196, 'mean_word_length': 4.916247906197655, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4524800', 'n_tokens_mistral': 1659, 'n_tokens_neox': 1546, 'n_words': 346}