2 #include <attr/xattr.h>
4 static int convertObj(PyObject *myobj, int *ishandle, int *filehandle, char **filename) {
5 if(PyString_Check(myobj)) {
7 *filename = PyString_AS_STRING(myobj);
8 } else if(PyInt_Check(myobj)) {
10 *filehandle = PyInt_AS_LONG(myobj);
11 } else if(PyFile_Check(myobj)) {
13 *filehandle = fileno(PyFile_AsFile(myobj));
14 if(*filehandle == -1) {
15 PyErr_SetFromErrno(PyExc_IOError);
19 PyErr_SetString(PyExc_TypeError, "argument 1 must be string or int");
26 pygetxattr(PyObject *self, PyObject *args)
37 /* Parse the arguments */
38 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 */
77 pysetxattr(PyObject *self, PyObject *args)
81 int ishandle, filedes;
88 /* Parse the arguments */
89 if (!PyArg_ParseTuple(args, "Oss#|b", &myarg, &attrname, &buf, &bufsize, &mode))
91 if(!convertObj(myarg, &ishandle, &filedes, &file))
94 /* Check the flags and convert them to libattr values */
95 flags = mode == 1 ? XATTR_CREATE : mode == 2 ? XATTR_REPLACE : 0;
97 /* Set the attribute's value */
99 fsetxattr(filedes, attrname, buf, bufsize, flags) :
100 setxattr(file, attrname, buf, bufsize, flags);
103 return PyErr_SetFromErrno(PyExc_IOError);
106 /* Return the result */
112 pyremovexattr(PyObject *self, PyObject *args)
116 int ishandle, filedes;
120 /* Parse the arguments */
121 if (!PyArg_ParseTuple(args, "Os", &myarg, &attrname))
124 if(!convertObj(myarg, &ishandle, &filedes, &file))
127 /* Remove the attribute */
129 fremovexattr(filedes, attrname) :
130 removexattr(file, attrname);
133 return PyErr_SetFromErrno(PyExc_IOError);
135 /* Return the result */
141 pylistxattr(PyObject *self, PyObject *args)
153 /* Parse the arguments */
154 if (!PyArg_ParseTuple(args, "O", &myarg))
157 if(!convertObj(myarg, &ishandle, &filedes, &file))
160 /* Find out the needed size of the buffer */
162 flistxattr(filedes, NULL, 0) :
163 listxattr(file, NULL, 0);
166 return PyErr_SetFromErrno(PyExc_IOError);
169 /* Try to allocate the memory, using Python's allocator */
170 if((buf = PyMem_Malloc(nalloc)) == NULL) {
175 /* Now retrieve the list of attributes */
177 flistxattr(filedes, buf, nalloc) :
178 listxattr(file, buf, nalloc);
180 return PyErr_SetFromErrno(PyExc_IOError);
183 /* Compute the number of attributes in the list */
184 for(s = buf, nattrs = 0; (s - buf) < nret; s += strlen(s) + 1) {
188 /* Create the tuple which will hold the result */
189 mytuple = PyTuple_New(nattrs);
191 /* Create and insert the attributes as strings in the tuple */
192 for(s = buf, nattrs = 0; s - buf < nret; s += strlen(s) + 1) {
193 PyTuple_SET_ITEM(mytuple, nattrs, PyString_FromString(s));
197 /* Free the buffer, now it is no longer needed */
200 /* Return the result */
204 static PyMethodDef AclMethods[] = {
205 {"getxattr", pygetxattr, METH_VARARGS,
206 "Get the value of a given extended attribute."},
207 {"setxattr", pysetxattr, METH_VARARGS,
208 "Set the value of a given extended attribute."},
209 {"removexattr", pyremovexattr, METH_VARARGS,
210 "Remove the a given extended attribute."},
211 {"listxattr", pylistxattr, METH_VARARGS,
212 "Retrieve the list of extened attributes."},
213 {NULL, NULL, 0, NULL} /* Sentinel */
219 (void) Py_InitModule("aclmodule", AclMethods);