summaryrefslogtreecommitdiff
blob: fc571d7325e314e8dc0e191d7dd913b655f45acc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* $Id$ */

#include "Python.h"

#include <sys/stat.h>

static char chflags_lchflags__doc__[];
static PyObject * chflags_lchflags(PyObject *self, PyObject *args);
static char chflags_lgetflags__doc__[];
static PyObject * chflags_lgetflags(PyObject *self, PyObject *args);
static char chflags_lhasproblems__doc__[];
static PyObject * chflags_lhasproblems(PyObject *self, PyObject *args);

static char chflags__doc__[] = "Provide some operations for manipulating" \
	"FreeBSD's filesystem flags";

static PyMethodDef chflags_methods[] = {
	{"lchflags", chflags_lchflags, METH_VARARGS, chflags_lchflags__doc__},
	{"lgetflags", chflags_lgetflags, METH_VARARGS, chflags_lgetflags__doc__},
	{"lhasproblems", chflags_lhasproblems, METH_VARARGS, chflags_lhasproblems__doc__},
	{NULL, NULL}
};

static char chflags_lchflags__doc__[] = 
"lchflags(path, flags) -> None\n\
Change the flags on path to equal flags.";

static char chflags_lgetflags__doc__[] =
"lgetflags(path) -> Integer\n\
Returns the file flags on path.";

static char chflags_lhasproblems__doc__[] = 
"lhasproblems(path) -> Integer\n\
Returns 1 if path has any flags set that prevent write operations;\n\
0 otherwise.";

static const unsigned long problemflags=0x00160016;

#if defined __FreeBSD__
static PyObject *chflags_lchflags(PyObject *self, PyObject *args) 
{
	char *path = NULL;
	int flags;
	int res;

	if (!PyArg_ParseTuple(args, "eti:lchflags",
			      Py_FileSystemDefaultEncoding, &path,
			      &flags))
	{
		return NULL;
	}

	res = lchflags(path, flags);

	PyMem_Free(path);
	return PyInt_FromLong((long)res);
}

static PyObject *chflags_lhasproblems(PyObject *self, PyObject *args)
{
	char *path = NULL;
	struct stat sb;
	int res;

	if (!PyArg_ParseTuple(args, "et:lhasproblems",
				Py_FileSystemDefaultEncoding, &path))
	{
		return NULL;
	}

	res = lstat(path, &sb);

	PyMem_Free(path);
		
	if (res < 0)
	{
		return PyInt_FromLong((long)res);
	}

	if (sb.st_flags & problemflags)
		return PyInt_FromLong(1);
	else
		return PyInt_FromLong(0);
}

static PyObject *chflags_lgetflags(PyObject *self, PyObject *args)
{
	char *path = NULL;
	struct stat sb;
	int res;

	if (!PyArg_ParseTuple(args, "et:lgetflags",
			      Py_FileSystemDefaultEncoding, &path))
	{
		return NULL;
	}

	res = lstat(path, &sb);

	if (res < 0)
	{
		PyMem_Free(path);
		return PyInt_FromLong((long)res);
	}

	PyMem_Free(path);

	return PyInt_FromLong((long)sb.st_flags);
}

#else
#warning Not on FreeBSD; building dummy lchflags

static PyObject *chflags_lgetflags(PyObject *self, PyObject *args)
{
	/* Obviously we can't set flags if the OS/filesystem doesn't support them. */
	return PyInt_FromLong(0);
}

static PyObject *chflags_lchflags(PyObject *self, PyObject *args)
{
	/* If file system flags aren't supported, just return 0,
	 as the effect is basically the same. */
	return PyInt_FromLong(0);
}

static PyObject *chflags_lhasproblems(PyObject *self, PyObject *args)
{
	return PyInt_FromLong(0);
}

#endif

static int ins(PyObject *m, char *symbolname, int value)
{
	return PyModule_AddIntConstant(m, symbolname, value);
}

DL_EXPORT(void) initchflags(void)
{
	PyObject *m;
	m = Py_InitModule4("chflags", chflags_methods, chflags__doc__,
			   (PyObject*)NULL, PYTHON_API_VERSION);
	
	ins(m, "UF_SETTABLE",  0x0000ffff);
	ins(m, "UF_NODUMP",    0x00000001);
	ins(m, "UF_IMMUTABLE", 0x00000002);
	ins(m, "UF_APPEND",    0x00000004);
	ins(m, "UF_OPAQUE",    0x00000008);
	ins(m, "UF_NOUNLINK",  0x00000010);

	ins(m, "SF_SETTABLE",  0xffff0000);
	ins(m, "SF_NODUMP",    0x00010000);
	ins(m, "SF_IMMUTABLE", 0x00020000);
	ins(m, "SF_APPEND",    0x00040000);
	ins(m, "SF_OPAQUE",    0x00080000);
	ins(m, "SF_NOUNLINK",  0x00100000);
	ins(m, "SF_SNAPSHOT",  0x00200000);

	ins(m, "PROBLEM_FLAGS", 0x00160016);
}