]> git.k1024.org Git - pyxattr.git/blob - xattr.c
Initial revision
[pyxattr.git] / xattr.c
1 #include <Python.h>
2 #include <attr/xattr.h>
3
4 static PyObject *
5 pygetxattr(PyObject *self, PyObject *args)
6 {
7     char *file;
8     char *attrname;
9     char *buf;
10     int nalloc, nret;
11     PyObject *res;
12     
13     if (!PyArg_ParseTuple(args, "ss", &file, &attrname))
14         return NULL;
15
16     if((nalloc = getxattr(file, attrname, NULL, 0)) == -1) {
17         return PyErr_SetFromErrno(PyExc_IOError);
18     }
19
20     if((buf = PyMem_Malloc(nalloc)) == NULL) {
21         PyErr_NoMemory();
22         return NULL;
23     }
24
25     if((nret = getxattr(file, attrname, buf, nalloc)) == -1) {
26         return PyErr_SetFromErrno(PyExc_IOError);
27     }
28
29     res = PyString_FromStringAndSize(buf, nret);
30     PyMem_Free(buf);
31     return res;
32 }
33
34 static PyObject *
35 pysetxattr(PyObject *self, PyObject *args)
36 {
37     char *file;
38     char *attrname;
39     char *buf;
40     char mode = 0;
41     int bufsize, nret;
42     int flags;
43     
44     if (!PyArg_ParseTuple(args, "sss#|b", &file, &attrname, &buf, &bufsize, &mode))
45         return NULL;
46
47     flags = mode == 1 ? XATTR_CREATE : mode == 2 ? XATTR_REPLACE : 0;
48     if((nret = setxattr(file, attrname, buf, bufsize, flags)) == -1) {
49         return PyErr_SetFromErrno(PyExc_IOError);
50     }
51
52     Py_INCREF(Py_None);
53     return Py_None;
54 }
55
56 static PyObject *
57 pyremovexattr(PyObject *self, PyObject *args)
58 {
59     char *file;
60     char *attrname;
61     
62     if (!PyArg_ParseTuple(args, "ss", &file, &attrname))
63         return NULL;
64
65     if(removexattr(file, attrname) == -1) {
66         return PyErr_SetFromErrno(PyExc_IOError);
67     }
68
69     Py_INCREF(Py_None);
70     return Py_None;
71 }
72
73 static PyObject *
74 pylistxattr(PyObject *self, PyObject *args)
75 {
76     char *file;
77     char *buf;
78     int nalloc, nret;
79     PyObject *mytuple;
80     int nattrs;
81     char *s;
82     
83     /* Parse the arguments */
84     if (!PyArg_ParseTuple(args, "s", &file))
85         return NULL;
86
87     /* Find out the needed size of the buffer */
88     if((nalloc = listxattr(file, NULL, 0)) == -1) {
89         return PyErr_SetFromErrno(PyExc_IOError);
90     }
91
92     /* Try to allocate the memory, using Python's allocator */
93     if((buf = PyMem_Malloc(nalloc)) == NULL) {
94         PyErr_NoMemory();
95         return NULL;
96     }
97
98     /* Now retrieve the list of attributes */
99     if((nret = listxattr(file, buf, nalloc)) == -1) {
100         return PyErr_SetFromErrno(PyExc_IOError);
101     }
102
103     /* Compute the number of attributes in the list */
104     for(s = buf, nattrs = 0; (s - buf) < nret; s += strlen(s) + 1) {
105         nattrs++;
106     }
107
108     /* Create the tuple which will hold the result */
109     mytuple = PyTuple_New(nattrs);
110
111     /* Create and insert the attributes as strings in the tuple */
112     for(s = buf, nattrs = 0; s - buf < nret; s += strlen(s) + 1) {
113         PyTuple_SET_ITEM(mytuple, nattrs, PyString_FromString(s));
114         nattrs++;
115     }
116
117     /* Free the buffer, now it is no longer needed */
118     PyMem_Free(buf);
119
120     /* Return the result */
121     return mytuple;
122 }
123
124 static PyMethodDef AclMethods[] = {
125     {"getxattr",  pygetxattr, METH_VARARGS,
126      "Get the value of a given extended attribute."},
127     {"setxattr",  pysetxattr, METH_VARARGS,
128      "Set the value of a given extended attribute."},
129     {"removexattr",  pyremovexattr, METH_VARARGS,
130      "Remove the a given extended attribute."},
131     {"listxattr",  pylistxattr, METH_VARARGS,
132      "Retrieve the list of extened attributes."},
133     {NULL, NULL, 0, NULL}        /* Sentinel */
134 };
135
136 void
137 initaclmodule(void)
138 {
139     (void) Py_InitModule("aclmodule", AclMethods);
140 }