1#include <unistd.h>
2#include <fcntl.h>
3#include <string.h>
4#include "selinux_internal.h"
5#include <stdlib.h>
6#include <errno.h>
7#include <sys/xattr.h>
8#include "policy.h"
9
10int getfilecon_raw(const char *path, char ** context)
11{
12	char *buf;
13	ssize_t size;
14	ssize_t ret;
15
16	size = INITCONTEXTLEN + 1;
17	buf = malloc(size);
18	if (!buf)
19		return -1;
20	memset(buf, 0, size);
21
22	ret = getxattr(path, XATTR_NAME_SELINUX, buf, size - 1);
23	if (ret < 0 && errno == ERANGE) {
24		char *newbuf;
25
26		size = getxattr(path, XATTR_NAME_SELINUX, NULL, 0);
27		if (size < 0)
28			goto out;
29
30		size++;
31		newbuf = realloc(buf, size);
32		if (!newbuf)
33			goto out;
34
35		buf = newbuf;
36		memset(buf, 0, size);
37		ret = getxattr(path, XATTR_NAME_SELINUX, buf, size - 1);
38	}
39      out:
40	if (ret == 0) {
41		/* Re-map empty attribute values to errors. */
42		errno = ENOTSUP;
43		ret = -1;
44	}
45	if (ret < 0)
46		free(buf);
47	else
48		*context = buf;
49	return ret;
50}
51
52
53int getfilecon(const char *path, char ** context)
54{
55	int ret;
56	char * rcontext = NULL;
57
58	*context = NULL;
59
60	ret = getfilecon_raw(path, &rcontext);
61
62	if (ret > 0) {
63		ret = selinux_raw_to_trans_context(rcontext, context);
64		freecon(rcontext);
65	}
66	if (ret >= 0 && *context)
67		return strlen(*context) + 1;
68
69	return ret;
70}
71
72