2 #include <attr/xattr.h>
4 /** Converts from a string, file or int argument to what we need. */
5 static int convertObj(PyObject *myobj, int *ishandle, int *filehandle, char **filename) {
6 if(PyString_Check(myobj)) {
8 *filename = PyString_AS_STRING(myobj);
9 } else if(PyInt_Check(myobj)) {
11 *filehandle = PyInt_AS_LONG(myobj);
12 } else if(PyFile_Check(myobj)) {
14 *filehandle = fileno(PyFile_AsFile(myobj));
15 if(*filehandle == -1) {
16 PyErr_SetFromErrno(PyExc_IOError);
20 PyErr_SetString(PyExc_TypeError, "argument 1 must be string or int");
26 /* Wrapper for getxattr */
28 pygetxattr(PyObject *self, PyObject *args)
32 int filedes, ishandle;
38 /* Parse the arguments */
39 if (!PyArg_ParseTuple(args, "Os", &myarg, &attrname))
41 if(!convertObj(myarg, &ishandle, &filedes, &file))
44 /* Find out the needed size of the buffer */
46 fgetxattr(filedes, attrname, NULL, 0) :
47 getxattr(file, attrname, NULL, 0);
49 return PyErr_SetFromErrno(PyExc_IOError);
52 /* Try to allocate the memory, using Python's allocator */
53 if((buf = PyMem_Malloc(nalloc)) == NULL) {
58 /* Now retrieve the attribute value */
60 fgetxattr(filedes, attrname, buf, nalloc) :
61 getxattr(file, attrname, buf, nalloc);
63 return PyErr_SetFromErrno(PyExc_IOError);
66 /* Create the string which will hold the result */
67 res = PyString_FromStringAndSize(buf, nret);
69 /* Free the buffer, now it is no longer needed */
72 /* Return the result */
76 /* Wrapper for setxattr */
78 pysetxattr(PyObject *self, PyObject *args)
82 int ishandle, filedes;
89 /* Parse the arguments */
90 if (!PyArg_ParseTuple(args, "Oss#|b", &myarg, &attrname, &buf, &bufsize, &mode))
92 if(!convertObj(myarg, &ishandle, &filedes, &file))
95 /* Check the flags and convert them to libattr values */
96 flags = mode == 1 ? XATTR_CREATE : mode == 2 ? XATTR_REPLACE : 0;
98 /* Set the attribute's value */
100 fsetxattr(filedes, attrname, buf, bufsize, flags) :
101 setxattr(file, attrname, buf, bufsize, flags);
104 return PyErr_SetFromErrno(PyExc_IOError);
107 /* Return the result */
112 /* Wrapper for removexattr */
114 pyremovexattr(PyObject *self, PyObject *args)
118 int ishandle, filedes;
122 /* Parse the arguments */
123 if (!PyArg_ParseTuple(args, "Os", &myarg, &attrname))
126 if(!convertObj(myarg, &ishandle, &filedes, &file))
129 /* Remove the attribute */
131 fremovexattr(filedes, attrname) :
132 removexattr(file, attrname);
135 return PyErr_SetFromErrno(PyExc_IOError);
137 /* Return the result */
142 /* Wrapper for listxattr */
144 pylistxattr(PyObject *self, PyObject *args)
156 /* Parse the arguments */
157 if (!PyArg_ParseTuple(args, "O", &myarg))
159 if(!convertObj(myarg, &ishandle, &filedes, &file))
162 /* Find out the needed size of the buffer */
164 flistxattr(filedes, NULL, 0) :
165 listxattr(file, NULL, 0);
168 return PyErr_SetFromErrno(PyExc_IOError);
171 /* Try to allocate the memory, using Python's allocator */
172 if((buf = PyMem_Malloc(nalloc)) == NULL) {
177 /* Now retrieve the list of attributes */
179 flistxattr(filedes, buf, nalloc) :
180 listxattr(file, buf, nalloc);
182 return PyErr_SetFromErrno(PyExc_IOError);
185 /* Compute the number of attributes in the list */
186 for(s = buf, nattrs = 0; (s - buf) < nret; s += strlen(s) + 1) {
190 /* Create the tuple which will hold the result */
191 mytuple = PyTuple_New(nattrs);
193 /* Create and insert the attributes as strings in the tuple */
194 for(s = buf, nattrs = 0; s - buf < nret; s += strlen(s) + 1) {
195 PyTuple_SET_ITEM(mytuple, nattrs, PyString_FromString(s));
199 /* Free the buffer, now it is no longer needed */
202 /* Return the result */
206 static PyMethodDef AclMethods[] = {
207 {"getxattr", pygetxattr, METH_VARARGS,
208 "Get the value of a given extended attribute."},
209 {"setxattr", pysetxattr, METH_VARARGS,
210 "Set the value of a given extended attribute."},
211 {"removexattr", pyremovexattr, METH_VARARGS,
212 "Remove the a given extended attribute."},
213 {"listxattr", pylistxattr, METH_VARARGS,
214 "Retrieve the list of extened attributes."},
215 {NULL, NULL, 0, NULL} /* Sentinel */
221 (void) Py_InitModule3("aclmodule", AclMethods, "Wrapper module for libattr");