From a5f57ccec46dae2f5f539cbd87c0950688f49ada Mon Sep 17 00:00:00 2001
From: Iustin Pop <iusty@k1024.org>
Date: Tue, 26 Feb 2008 20:48:11 +0100
Subject: [PATCH] Imported upstream version 0.2.2

---
 BENCHMARK      |   20 +
 ChangeLog      |  108 ++++
 IMPLEMENTATION |   36 ++
 MANIFEST       |   12 +
 PKG-INFO       |   12 +
 PLATFORMS      |   23 +
 README         |    6 +
 acl.c          | 1302 ++++++++++++++++++++++++++++++++++++++++++++++++
 os_linux.c     |    6 +
 posix1e.html   |  414 +++++++++++++++
 posix1e.txt    |  443 ++++++++++++++++
 setup.cfg      |    4 +
 setup.py       |   44 ++
 13 files changed, 2430 insertions(+)
 create mode 100644 BENCHMARK
 create mode 100644 ChangeLog
 create mode 100644 IMPLEMENTATION
 create mode 100644 MANIFEST
 create mode 100644 PKG-INFO
 create mode 100644 PLATFORMS
 create mode 100644 README
 create mode 100644 acl.c
 create mode 100644 os_linux.c
 create mode 100644 posix1e.html
 create mode 100644 posix1e.txt
 create mode 100644 setup.cfg
 create mode 100755 setup.py

diff --git a/BENCHMARK b/BENCHMARK
new file mode 100644
index 0000000..3c9cea1
--- /dev/null
+++ b/BENCHMARK
@@ -0,0 +1,20 @@
+On my Duron 1000, Linux 2.4, creating 1.000.000 ACLs and discarding them:
+
+empty ACL:  4.48user  0.03system 0:04.50elapsed 100%CPU
+from text: 13.87user  0.09system 0:13.97elapsed  99%CPU
+XFS, file: 14.17user 14.95system 0:29.13elapsed  99%CPU
+
+creating a list from the entries of an ACL:
+no entries: 3.86user 0.01system 0:03.86elapsed 100%CPU
+6 entries: 16.39user 0.00system 0:16.38elapsed 100%CPU
+
+As you can see, creating from file is the longest (as expected). More than
+half time when creating from file was in kernel mode.
+
+
+In freebsd 4.6, UNDER VMWARE!!!!, same machine:
+empty ACL:  3.409u 0.432s 0:03.85 99.4%    516+15695k 0+0io 0pf+0w
+from text: 10.672u 1.016s 0:11.71 99.7%    508+24230k 0+0io 0pf+0w
+
+Interesting results, it seems from text is faster here - but here
+the library doens't support editing, so maybe that's why.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..35f2eb4
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,108 @@
+2006-12-03 11:15  Iustin Pop <iusty@k1024.org>
+
+	* setup.py: Add support for building on GNU/kFreeBSD
+
+2004-04-27 20:27  Iustin Pop <iusty@k1024.org>
+
+	* MANIFEST.in: Added ChangeLog to distribution
+
+2002-12-29 20:41  Iustin Pop <iusty@k1024.org>
+
+	* BENCHMARK, MANIFEST.in, setup.py: Release 0.2.1
+
+2002-12-29 06:48  Iustin Pop <iusty@k1024.org>
+
+	* acl.c: Fixed compilation on LEVEL1 platform (broke since after
+	  0.1)
+
+2002-12-29 06:36  Iustin Pop <iusty@k1024.org>
+
+	* BENCHMARK, acl.c: Added missing functionality (acl_calc_mask) and
+	  some convenience functions.
+
+2002-12-27 21:55  Iustin Pop <iusty@k1024.org>
+
+	* MANIFEST.in, setup.py: Small changes
+
+2002-12-27 19:47  Iustin Pop <iusty@k1024.org>
+
+	* IMPLEMENTATION, acl.c: Prepare for release 0.2
+
+2002-12-27 19:43  Iustin Pop <iusty@k1024.org>
+
+	* Makefile: Small makefile
+
+2002-12-27 19:42  Iustin Pop <iusty@k1024.org>
+
+	* MANIFEST.in: Distutils file
+
+2002-12-27 19:42  Iustin Pop <iusty@k1024.org>
+
+	* os_linux.c: Linux-specific file
+
+2002-12-27 11:35  Iustin Pop <iusty@k1024.org>
+
+	* PORTING: Informations for porting to other platforms.
+
+2002-12-26 09:21  Iustin Pop <iusty@k1024.org>
+
+	* acl.c: Added the Permset type/object and some other naming
+	  changes
+
+2002-12-26 06:48  Iustin Pop <iusty@k1024.org>
+
+	* acl.c: Renamed type & object names from ACLType to ACL_Type and
+	  so on. Also ACLEntry is now jus Entry.
+
+2002-12-26 06:43  Iustin Pop <iusty@k1024.org>
+
+	* acl.c: Renamed some fields from ob_x to x, as per other modules
+	  in python
+
+2002-12-26 06:41  Iustin Pop <iusty@k1024.org>
+
+	* IMPLEMENTATION, acl.c: Added acl_entry_t type (named
+	  ACLEntryType, respectively ACLEntryObject)
+
+2002-12-26 03:24  Iustin Pop <iusty@k1024.org>
+
+	* acl.c: Documentation typo
+
+2002-12-24 15:35  Iustin Pop <iusty@k1024.org>
+
+	* setup.cfg: Added setup.cfg, mainly for bdist_rpm
+
+2002-12-24 15:29  Iustin Pop <iusty@k1024.org>
+
+	* setup.py: Don't call python2, only python
+
+2002-12-24 15:19  Iustin Pop <iusty@k1024.org>
+
+	* acl.c, setup.py: Prepare for first public release
+
+2002-12-24 03:35  Iustin Pop <iusty@k1024.org>
+
+	* PLATFORMS, acl.c, setup.py: Moved to real instance creation via
+	  type()
+
+2002-12-23 21:05  Iustin Pop <iusty@k1024.org>
+
+	* IMPLEMENTATION, PLATFORMS, README, acl.c, setup.py: Addedd
+	  __setstate__ and some docs
+
+2002-12-23 16:55  Iustin Pop <iusty@k1024.org>
+
+	* README, setup.py: Initial revision
+
+2002-12-23 16:55  Iustin Pop <iusty@k1024.org>
+
+	* acl.c: Many functions added, started working on level 2 support
+
+2002-12-21 21:55  Iustin Pop <iusty@k1024.org>
+
+	* acl.c: Initial revision
+
+2002-12-21 21:55  
+
+	* branches, tags, .: New repository initialized by cvs2svn.
+
diff --git a/IMPLEMENTATION b/IMPLEMENTATION
new file mode 100644
index 0000000..64ad4a5
--- /dev/null
+++ b/IMPLEMENTATION
@@ -0,0 +1,36 @@
+The IEEE 1003.1e draft 17 ("POSIX.1e") describes a set of 28
+functions. These are grouped into three groups, based on their
+portability: 
+    - first group, the most portable one. All systems which claim to
+      support POSIX.1e should implement these: 
+     acl_delete_def_file(3), acl_dup(3), acl_free(3), acl_from_text(3),
+     acl_get_fd(3), acl_get_file(3), acl_init(3), acl_set_fd(3),
+     acl_set_file(3), acl_to_text(3), acl_valid(3)
+
+    - second group, containing the rest of the POSIX ACL functions. Systems
+      which claim to fully implement POSIX.1e should implement these:
+     acl_add_perm(3), acl_calc_mask(3), acl_clear_perms(3), acl_copy_entry(3),
+     acl_copy_ext(3), acl_copy_int(3), acl_create_entry(3),
+     acl_delete_entry(3), acl_delete_perm(3), acl_get_entry(3),
+     acl_get_permset(3), acl_get_qualifier(3), acl_get_tag_type(3),
+     acl_set_permset(3), acl_set_qualifier(3), acl_set_tag_type(3),
+     acl_size(3)
+
+    - third group, containing extra functions implemented by each OS. These
+      are non-portable version. Both Linux and FreeBSD implement some extra 
+      function.
+
+Thus we have the level of compliance. Depending on whether the system
+library support the second group, you get some extra methods for the
+ACL object.
+
+Internal structure
+    The POSIX draft has the following stuff (correct me if I'm wrong):
+        - an ACL is denoted by acl_t
+        - an ACL contains many acl_entry_t, these are the individual entries
+          in the list; they always! belong to an acl_t
+        - each entry_t has a qualifier (think uid_t or gid_t), whose type is 
+          denoted by the acl_tag_t type, and an acl_permset_t
+        - the acl_permset_t can contain acl_perm_t value (ACL_READ, ACL_WRITE,
+          ACL_EXECUTE, ACL_ADD, ACL_DELETE, ...)
+        - function to manipulate all these, and functions to manipulate files
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..6d339f4
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,12 @@
+BENCHMARK
+ChangeLog
+IMPLEMENTATION
+MANIFEST
+PLATFORMS
+README
+acl.c
+os_linux.c
+posix1e.html
+posix1e.txt
+setup.cfg
+setup.py
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..1752799
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,12 @@
+Metadata-Version: 1.0
+Name: pylibacl
+Version: 0.2.2
+Summary: POSIX.1e ACLs for python
+Home-page: http://pylibacl.sourceforge.net
+Author: Iustin Pop
+Author-email: iusty@k1024.org
+License: GPL
+Description: This is a C extension module for Python which
+        implements POSIX ACLs manipulation. It is a wrapper on top
+        of the systems's acl C library - see acl(5).
+Platform: UNKNOWN
diff --git a/PLATFORMS b/PLATFORMS
new file mode 100644
index 0000000..ab2d28b
--- /dev/null
+++ b/PLATFORMS
@@ -0,0 +1,23 @@
+The current supported platforms:
+
+Linux 
+
+    It needs kernel 2.4 or higher and the libacl library installed (with
+    development headers, if installing from rpm). The url is
+    http://acl.bestbits.at if using for ext2/ext3 and JFS, and
+    http://oss.sgi.com/projects/xfs/ if using for XFS.
+
+    The level of compliance is level 2 (see IMPLEMENTATION).
+
+
+FreeBSD
+
+    The current tested version is 4.6. I hope to be able to test 5.0 after
+    it's released.
+
+    The level of compliance is level 1. I hope that in FreeBSD 5 they will
+    improve.
+
+
+For any other platform, volunteers are welcome. To add support, look
+into setup.py at first and then into acl.c
diff --git a/README b/README
new file mode 100644
index 0000000..e17837d
--- /dev/null
+++ b/README
@@ -0,0 +1,6 @@
+This is an extension for Python which implements POSIX ACLs (POSIX.1e).
+
+To see the supported platforms, look at PLATFORMS.
+To see internal details, look at IMPLEMENTATION.
+
+Iustin Pop, <iusty@k1024.org>
diff --git a/acl.c b/acl.c
new file mode 100644
index 0000000..e4248a6
--- /dev/null
+++ b/acl.c
@@ -0,0 +1,1302 @@
+#include <Python.h>
+
+#include <sys/types.h>
+#include <sys/acl.h>
+
+#ifdef HAVE_LINUX
+#include "os_linux.c"
+#endif
+
+staticforward PyTypeObject ACL_Type;
+static PyObject* ACL_applyto(PyObject* obj, PyObject* args);
+static PyObject* ACL_valid(PyObject* obj, PyObject* args);
+
+#ifdef HAVE_LEVEL2
+static PyObject* ACL_get_state(PyObject *obj, PyObject* args);
+static PyObject* ACL_set_state(PyObject *obj, PyObject* args);
+
+staticforward PyTypeObject Entry_Type;
+staticforward PyTypeObject Permset_Type;
+static PyObject* Permset_new(PyTypeObject* type, PyObject* args, PyObject *keywds);
+#endif
+
+static acl_perm_t holder_ACL_EXECUTE = ACL_EXECUTE;
+static acl_perm_t holder_ACL_READ = ACL_READ;
+static acl_perm_t holder_ACL_WRITE = ACL_WRITE;
+
+typedef struct {
+    PyObject_HEAD
+    acl_t acl;
+#ifdef HAVE_LEVEL2
+    int entry_id;
+#endif
+} ACL_Object;
+
+#ifdef HAVE_LEVEL2
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *parent_acl; /* The parent acl, so it won't run out on us */
+    acl_entry_t entry;
+} Entry_Object;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *parent_entry; /* The parent entry, so it won't run out on us */
+    acl_permset_t permset;
+} Permset_Object;
+
+#endif
+
+/* Creation of a new ACL instance */
+static PyObject* ACL_new(PyTypeObject* type, PyObject* args, PyObject *keywds) {
+    PyObject* newacl;
+
+    newacl = type->tp_alloc(type, 0);
+
+    if(newacl != NULL) {
+        ((ACL_Object*)newacl)->acl = NULL;
+#ifdef HAVEL_LEVEL2
+        ((ACL_Object*)newacl)->entry_id = ACL_FIRST_ENTRY;
+#endif
+    }
+
+    return newacl;
+}
+
+/* Initialization of a new ACL instance */
+static int ACL_init(PyObject* obj, PyObject* args, PyObject *keywds) {
+    ACL_Object* self = (ACL_Object*) obj;
+    static char *kwlist[] = { "file", "fd", "text", "acl", "filedef", NULL };
+    char *file = NULL;
+    char *filedef = NULL;
+    char *text = NULL;
+    int fd = -1;
+    ACL_Object* thesrc = NULL;
+
+    if(!PyTuple_Check(args) || PyTuple_Size(args) != 0 ||
+       (keywds != NULL && PyDict_Check(keywds) && PyDict_Size(keywds) > 1)) {
+        PyErr_SetString(PyExc_ValueError, "a max of one keyword argument must be passed");
+        return -1;
+    }
+    if(!PyArg_ParseTupleAndKeywords(args, keywds, "|sisO!s", kwlist,
+                                     &file, &fd, &text, &ACL_Type, &thesrc, &filedef))
+        return -1;
+
+    /* Free the old acl_t without checking for error, we don't
+     * care right now */
+    if(self->acl != NULL)
+        acl_free(self->acl);
+
+    if(file != NULL)
+        self->acl = acl_get_file(file, ACL_TYPE_ACCESS);
+    else if(text != NULL)
+        self->acl = acl_from_text(text);
+    else if(fd != -1)
+        self->acl = acl_get_fd(fd);
+    else if(thesrc != NULL)
+        self->acl = acl_dup(thesrc->acl);
+    else if(filedef != NULL)
+        self->acl = acl_get_file(filedef, ACL_TYPE_DEFAULT);
+    else
+        self->acl = acl_init(0);
+
+    if(self->acl == NULL) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return -1;
+    }
+
+    return 0;
+}
+
+/* Standard type functions */
+static void ACL_dealloc(PyObject* obj) {
+    ACL_Object *self = (ACL_Object*) obj;
+    PyObject *err_type, *err_value, *err_traceback;
+    int have_error = PyErr_Occurred() ? 1 : 0;
+
+    if (have_error)
+        PyErr_Fetch(&err_type, &err_value, &err_traceback);
+    if(self->acl != NULL && acl_free(self->acl) != 0)
+        PyErr_WriteUnraisable(obj);
+    if (have_error)
+        PyErr_Restore(err_type, err_value, err_traceback);
+    PyObject_DEL(self);
+}
+
+/* Converts the acl to a text format */
+static PyObject* ACL_str(PyObject *obj) {
+    char *text;
+    ACL_Object *self = (ACL_Object*) obj;
+    PyObject *ret;
+
+    text = acl_to_text(self->acl, NULL);
+    if(text == NULL) {
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+    ret = PyString_FromString(text);
+    if(acl_free(text) != 0) {
+        Py_DECREF(ret);
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+    return ret;
+}
+
+/* Custom methods */
+static char __applyto_doc__[] = \
+"Apply the ACL to a file or filehandle.\n" \
+"\n" \
+"Parameters:\n" \
+"  - either a filename or a file-like object or an integer; this\n" \
+"    represents the filesystem object on which to act\n" \
+"  - optional flag representing the type of ACL to set, either\n" \
+"    ACL_TYPE_ACCESS (default) or ACL_TYPE_DEFAULT\n" \
+;
+
+/* Applyes the ACL to a file */
+static PyObject* ACL_applyto(PyObject* obj, PyObject* args) {
+    ACL_Object *self = (ACL_Object*) obj;
+    PyObject *myarg;
+    acl_type_t type = ACL_TYPE_ACCESS;
+    int nret;
+    int fd;
+
+    if (!PyArg_ParseTuple(args, "O|i", &myarg, &type))
+        return NULL;
+
+    if(PyString_Check(myarg)) {
+        char *filename = PyString_AS_STRING(myarg);
+        nret = acl_set_file(filename, type, self->acl);
+    } else if((fd = PyObject_AsFileDescriptor(myarg)) != -1) {
+        nret = acl_set_fd(fd, self->acl);
+    } else {
+        PyErr_SetString(PyExc_TypeError, "argument 1 must be string, int, or file-like object");
+        return 0;
+    }
+    if(nret == -1) {
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+
+    /* Return the result */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static char __valid_doc__[] = \
+"Test the ACL for validity.\n" \
+"\n" \
+"This method tests the ACL to see if it is a valid ACL\n" \
+"in terms of the filesystem. More precisely, it checks:\n" \
+"A valid ACL contains exactly one entry with each of the ACL_USER_OBJ,\n" \
+"ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries with ACL_USER and\n" \
+"ACL_GROUP tag types may appear zero or more times in an ACL. An ACL that\n" \
+"contains entries of ACL_USER or ACL_GROUP tag types must contain exactly\n" \
+"one entry of the ACL_MASK tag type. If an ACL contains no entries of\n" \
+"ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional.\n" \
+"\n" \
+"All user ID qualifiers must be unique among all entries of ACL_USER tag\n" \
+"type, and all group IDs must be unique among all entries of ACL_GROUP tag\n" \
+"type.\n" \
+"\n" \
+"The method will return 1 for a valid ACL and 0 for an invalid one.\n" \
+"This has been chosen because the specification for acl_valid in POSIX.1e\n" \
+"documents only one possible value for errno in case of an invalid ACL, \n" \
+"so we can't differentiate between classes of errors. Other suggestions \n" \
+"are welcome.\n" \
+;
+
+/* Checks the ACL for validity */
+static PyObject* ACL_valid(PyObject* obj, PyObject* args) {
+    ACL_Object *self = (ACL_Object*) obj;
+
+    if(acl_valid(self->acl) == -1) {
+        Py_INCREF(Py_False);
+        return Py_False;
+    } else {
+        Py_INCREF(Py_True);
+        return Py_True;
+    }
+}
+
+#ifdef HAVE_LEVEL2
+
+static PyObject* ACL_get_state(PyObject *obj, PyObject* args) {
+    ACL_Object *self = (ACL_Object*) obj;
+    PyObject *ret;
+    ssize_t size, nsize;
+    char *buf;
+
+    size = acl_size(self->acl);
+    if(size == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    if((ret = PyString_FromStringAndSize(NULL, size)) == NULL)
+        return NULL;
+    buf = PyString_AsString(ret);
+    
+    if((nsize = acl_copy_ext(buf, self->acl, size)) == -1) {
+        Py_DECREF(ret);
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+    
+    return ret;
+}
+
+static PyObject* ACL_set_state(PyObject *obj, PyObject* args) {
+    ACL_Object *self = (ACL_Object*) obj;
+    const void *buf;
+    int bufsize;
+    acl_t ptr;
+
+    /* Parse the argument */
+    if (!PyArg_ParseTuple(args, "s#", &buf, &bufsize))
+        return NULL;
+
+    /* Try to import the external representation */
+    if((ptr = acl_copy_int(buf)) == NULL)
+        return PyErr_SetFromErrno(PyExc_IOError);
+        
+    /* Free the old acl. Should we ignore errors here? */
+    if(self->acl != NULL) {
+        if(acl_free(self->acl) == -1)
+            return PyErr_SetFromErrno(PyExc_IOError);
+    }
+
+    self->acl = ptr;
+
+    /* Return the result */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/* tp_iter for the ACL type; since it can be iterated only
+ * destructively, the type is its iterator
+ */
+static PyObject* ACL_iter(PyObject *obj) {
+    ACL_Object *self = (ACL_Object*)obj;
+    self->entry_id = ACL_FIRST_ENTRY;
+    Py_INCREF(obj);
+    return obj;
+}
+
+/* the tp_iternext function for the ACL type */
+static PyObject* ACL_iternext(PyObject *obj) {
+    ACL_Object *self = (ACL_Object*)obj;
+    acl_entry_t the_entry_t;
+    Entry_Object *the_entry_obj;
+    int nerr;
+    
+    nerr = acl_get_entry(self->acl, self->entry_id, &the_entry_t);
+    self->entry_id = ACL_NEXT_ENTRY;
+    if(nerr == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+    else if(nerr == 0) {
+        /* Docs says this is not needed */
+        /*PyErr_SetObject(PyExc_StopIteration, Py_None);*/
+        return NULL;
+    }
+
+    the_entry_obj = (Entry_Object*) PyType_GenericNew(&Entry_Type, NULL, NULL);
+    if(the_entry_obj == NULL)
+        return NULL;
+    
+    the_entry_obj->entry = the_entry_t;
+
+    the_entry_obj->parent_acl = obj;
+    Py_INCREF(obj); /* For the reference we have in entry->parent */
+
+    return (PyObject*)the_entry_obj;
+}
+
+static char __ACL_delete_entry_doc__[] = \
+"Deletes an entry from the ACL.\n" \
+"\n" \
+"Note: Only with level 2\n" \
+"Parameters:\n" \
+" - the Entry object which should be deleted; note that after\n" \
+"   this function is called, that object is unusable any longer\n" \
+"   and should be deleted\n" \
+;
+
+/* Deletes an entry from the ACL */
+static PyObject* ACL_delete_entry(PyObject *obj, PyObject *args) {
+    ACL_Object *self = (ACL_Object*)obj;
+    Entry_Object *e;
+
+    if (!PyArg_ParseTuple(args, "O!", &Entry_Type, &e))
+        return NULL;
+
+    if(acl_delete_entry(self->acl, e->entry) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    /* Return the result */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static char __ACL_calc_mask_doc__[] = \
+"Compute the file group class mask.\n" \
+"\n" \
+"The calc_mask() method calculates and sets the permissions \n" \
+"associated with the ACL_MASK Entry of the ACL.\n" \
+"The value of the new permissions is the union of the permissions \n" \
+"granted by all entries of tag type ACL_GROUP, ACL_GROUP_OBJ, or \n" \
+"ACL_USER.  If the ACL already contains an ACL_MASK entry, its \n" \
+"permissions are overwritten; if it does not contain an ACL_MASK \n" \
+"Entry, one is added.\n" \
+"\n" \
+"The order of existing entries in the ACL is undefined after this \n" \
+"function.\n" \
+;
+
+/* Updates the mask entry in the ACL */
+static PyObject* ACL_calc_mask(PyObject *obj, PyObject *args) {
+    ACL_Object *self = (ACL_Object*)obj;
+    
+    if(acl_calc_mask(&self->acl) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    /* Return the result */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static char __ACL_append_doc__[] = \
+"Append a new Entry to the ACL and return it.\n" \
+"\n" \
+"This is a convenience function to create a new Entry \n" \
+"and append it to the ACL.\n" \
+"If a parameter of type Entry instance is given, the \n" \
+"entry will be a copy of that one (as if copied with \n" \
+"Entry.copy()), otherwise, the new entry will be empty.\n" \
+;
+
+/* Convenience method to create a new Entry */
+static PyObject* ACL_append(PyObject *obj, PyObject *args) {
+    ACL_Object* self = (ACL_Object*) obj;
+    Entry_Object* newentry;
+    Entry_Object* oldentry = NULL;
+    int nret;
+
+    newentry = (Entry_Object*)PyType_GenericNew(&Entry_Type, NULL, NULL);
+    if(newentry == NULL) {
+        return NULL;
+    }
+
+    if (!PyArg_ParseTuple(args, "|O!", &Entry_Type, &oldentry))
+        return NULL;
+
+    nret = acl_create_entry(&self->acl, &newentry->entry);
+    if(nret == -1) {
+        Py_DECREF(newentry);
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+
+    if(oldentry != NULL) {
+        nret = acl_copy_entry(newentry->entry, oldentry->entry);
+        if(nret == -1) {
+            Py_DECREF(newentry);
+            return PyErr_SetFromErrno(PyExc_IOError);
+        }
+    }
+
+    newentry->parent_acl = obj;
+    Py_INCREF(obj);
+    
+    return (PyObject*)newentry;
+}
+
+/***** Entry type *****/
+
+/* Creation of a new Entry instance */
+static PyObject* Entry_new(PyTypeObject* type, PyObject* args, PyObject *keywds) {
+    PyObject* newentry;
+
+    newentry = PyType_GenericNew(type, args, keywds);
+
+    if(newentry != NULL) {
+        ((Entry_Object*)newentry)->entry = NULL;
+        ((Entry_Object*)newentry)->parent_acl = NULL;
+    }
+
+    return newentry;
+}
+
+/* Initialization of a new Entry instance */
+static int Entry_init(PyObject* obj, PyObject* args, PyObject *keywds) {
+    Entry_Object* self = (Entry_Object*) obj;
+    ACL_Object* parent = NULL;
+
+    if (!PyArg_ParseTuple(args, "O!", &ACL_Type, &parent))
+        return -1;
+
+    if(acl_create_entry(&parent->acl, &self->entry) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return -1;
+    }
+
+    self->parent_acl = (PyObject*)parent;
+    Py_INCREF(parent);
+
+    return 0;
+}
+
+/* Free the Entry instance */
+static void Entry_dealloc(PyObject* obj) {
+    Entry_Object *self = (Entry_Object*) obj;
+    PyObject *err_type, *err_value, *err_traceback;
+    int have_error = PyErr_Occurred() ? 1 : 0;
+
+    if (have_error)
+        PyErr_Fetch(&err_type, &err_value, &err_traceback);
+    if(self->parent_acl != NULL) {
+        Py_DECREF(self->parent_acl);
+        self->parent_acl = NULL;
+    }
+    if (have_error)
+        PyErr_Restore(err_type, err_value, err_traceback);
+    PyObject_DEL(self);
+}
+
+/* Converts the entry to a text format */
+static PyObject* Entry_str(PyObject *obj) {
+    acl_tag_t tag;
+    uid_t qualifier;
+    void *p;
+    PyObject *ret;
+    PyObject *format, *list;
+    Entry_Object *self = (Entry_Object*) obj;
+
+    if(acl_get_tag_type(self->entry, &tag) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    if(tag == ACL_USER || tag == ACL_GROUP) {
+        if((p = acl_get_qualifier(self->entry)) == NULL) {
+            PyErr_SetFromErrno(PyExc_IOError);
+            return NULL;
+        }
+        qualifier = *(uid_t*)p;
+        acl_free(p);
+    } else {
+        qualifier = 0;
+    }
+    
+    format = PyString_FromString("ACL entry for %s");
+    if(format == NULL)
+        return NULL;
+    list = PyTuple_New(1);
+    if(tag == ACL_UNDEFINED_TAG) {
+        PyTuple_SetItem(list, 0, PyString_FromString("undefined type"));
+    } else if(tag == ACL_USER_OBJ) {
+        PyTuple_SetItem(list, 0, PyString_FromString("the owner"));
+    } else if(tag == ACL_GROUP_OBJ) {
+        PyTuple_SetItem(list, 0, PyString_FromString("the group"));
+    } else if(tag == ACL_OTHER) {
+        PyTuple_SetItem(list, 0, PyString_FromString("the others"));
+    } else if(tag == ACL_USER) {
+        PyTuple_SetItem(list, 0, PyString_FromFormat("user with uid %d", qualifier));
+    } else if(tag == ACL_GROUP) {
+        PyTuple_SetItem(list, 0, PyString_FromFormat("group with gid %d", qualifier));
+    } else if(tag == ACL_MASK) {
+        PyTuple_SetItem(list, 0, PyString_FromString("the mask"));
+    } else {
+        PyTuple_SetItem(list, 0, PyString_FromString("UNKNOWN_TAG_TYPE!"));
+    }
+    ret = PyString_Format(format, list);
+    Py_DECREF(format);
+    Py_DECREF(list);
+    return ret;
+}
+
+/* Sets the tag type of the entry */
+static int Entry_set_tag_type(PyObject* obj, PyObject* value, void* arg) {
+    Entry_Object *self = (Entry_Object*) obj;
+
+    if(value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "tag type deletion is not supported");
+        return -1;
+    }
+
+    if(!PyInt_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "tag type must be integer");
+        return -1;
+    }
+    if(acl_set_tag_type(self->entry, (acl_tag_t)PyInt_AsLong(value)) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return -1;
+    }
+
+    return 0;
+}
+
+/* Returns the tag type of the entry */
+static PyObject* Entry_get_tag_type(PyObject *obj, void* arg) {
+    Entry_Object *self = (Entry_Object*) obj;
+    acl_tag_t value;
+
+    if (self->entry == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "entry attribute");
+        return NULL;
+    }
+    if(acl_get_tag_type(self->entry, &value) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+
+    return PyInt_FromLong(value);
+}
+
+/* Sets the qualifier (either uid_t or gid_t) for the entry,
+ * usable only if the tag type if ACL_USER or ACL_GROUP
+ */
+static int Entry_set_qualifier(PyObject* obj, PyObject* value, void* arg) {
+    Entry_Object *self = (Entry_Object*) obj;
+    int uidgid;
+
+    if(value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "qualifier deletion is not supported");
+        return -1;
+    }
+
+    if(!PyInt_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "tag type must be integer");
+        return -1;
+    }
+    uidgid = PyInt_AsLong(value);
+    if(acl_set_qualifier(self->entry, (void*)&uidgid) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return -1;
+    }
+
+    return 0;
+}
+
+/* Returns the qualifier of the entry */
+static PyObject* Entry_get_qualifier(PyObject *obj, void* arg) {
+    Entry_Object *self = (Entry_Object*) obj;
+    void *p;
+    int value;
+
+    if (self->entry == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "entry attribute");
+        return NULL;
+    }
+    if((p = acl_get_qualifier(self->entry)) == NULL) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    value = *(uid_t*)p;
+    acl_free(p);
+    
+    return PyInt_FromLong(value);
+}
+
+/* Returns the parent ACL of the entry */
+static PyObject* Entry_get_parent(PyObject *obj, void* arg) {
+    Entry_Object *self = (Entry_Object*) obj;
+    
+    Py_INCREF(self->parent_acl);
+    return self->parent_acl;
+}
+
+/* Returns the a new Permset representing the permset of the entry 
+ * FIXME: Should return a new reference to the same object, which
+ * should be created at init time!
+*/
+static PyObject* Entry_get_permset(PyObject *obj, void* arg) {
+    Entry_Object *self = (Entry_Object*)obj;
+    PyObject *p;
+    Permset_Object *ps;
+
+    p = Permset_new(&Permset_Type, NULL, NULL);
+    if(p == NULL)
+        return NULL;
+    ps = (Permset_Object*)p;
+    if(acl_get_permset(self->entry, &ps->permset) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+    ps->parent_entry = obj;
+    Py_INCREF(obj);
+
+    return (PyObject*)p;
+}
+
+/* Sets the permset of the entry to the passed Permset */
+static int Entry_set_permset(PyObject* obj, PyObject* value, void* arg) {
+    Entry_Object *self = (Entry_Object*)obj;
+    Permset_Object *p;
+
+    if(!PyObject_IsInstance(value, (PyObject*)&Permset_Type)) {
+        PyErr_SetString(PyExc_TypeError, "argument 1 must be posix1e.Permset");
+        return -1;
+    }
+    p = (Permset_Object*)value;
+    if(acl_set_permset(self->entry, p->permset) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return -1;
+    }
+    return 0;
+}
+
+static char __Entry_copy_doc__[] = \
+"Copy an ACL entry.\n" \
+"\n" \
+"This method sets all the parameters to those of another\n" \
+"entry, even one of another's ACL\n" \
+"Parameters:\n" \
+" - src, instance of type Entry\n" \
+;
+
+/* Sets all the entry parameters to another's entry */
+static PyObject* Entry_copy(PyObject *obj, PyObject *args) {
+    Entry_Object *self = (Entry_Object*)obj;
+    Entry_Object *other;
+    
+    if(!PyArg_ParseTuple(args, "O!", &Entry_Type, &other))
+        return NULL;
+
+    if(acl_copy_entry(self->entry, other->entry) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/**** Permset type *****/
+
+/* Creation of a new Permset instance */
+static PyObject* Permset_new(PyTypeObject* type, PyObject* args, PyObject *keywds) {
+    PyObject* newpermset;
+
+    newpermset = PyType_GenericNew(type, args, keywds);
+
+    if(newpermset != NULL) {
+        ((Permset_Object*)newpermset)->permset = NULL;
+        ((Permset_Object*)newpermset)->parent_entry = NULL;
+    }
+
+    return newpermset;
+}
+
+/* Initialization of a new Permset instance */
+static int Permset_init(PyObject* obj, PyObject* args, PyObject *keywds) {
+    Permset_Object* self = (Permset_Object*) obj;
+    Entry_Object* parent = NULL;
+
+    if (!PyArg_ParseTuple(args, "O!", &Entry_Type, &parent))
+        return -1;
+
+    if(acl_get_permset(parent->entry, &self->permset) == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return -1;
+    }
+
+    self->parent_entry = (PyObject*)parent;
+    Py_INCREF(parent);
+
+    return 0;
+}
+
+/* Free the Permset instance */
+static void Permset_dealloc(PyObject* obj) {
+    Permset_Object *self = (Permset_Object*) obj;
+    PyObject *err_type, *err_value, *err_traceback;
+    int have_error = PyErr_Occurred() ? 1 : 0;
+
+    if (have_error)
+        PyErr_Fetch(&err_type, &err_value, &err_traceback);
+    if(self->parent_entry != NULL) {
+        Py_DECREF(self->parent_entry);
+        self->parent_entry = NULL;
+    }
+    if (have_error)
+        PyErr_Restore(err_type, err_value, err_traceback);
+    PyObject_DEL(self);
+}
+
+/* Permset string representation */
+static PyObject* Permset_str(PyObject *obj) {
+    Permset_Object *self = (Permset_Object*) obj;
+    char pstr[3];
+
+    pstr[0] = get_perm(self->permset, ACL_READ) ? 'r' : '-';
+    pstr[1] = get_perm(self->permset, ACL_WRITE) ? 'w' : '-';
+    pstr[2] = get_perm(self->permset, ACL_EXECUTE) ? 'x' : '-';
+    return PyString_FromStringAndSize(pstr, 3);
+}
+
+static char __Permset_clear_doc__[] = \
+"Clear all permissions from the permission set.\n" \
+;
+
+/* Clears all permissions from the permset */
+static PyObject* Permset_clear(PyObject* obj, PyObject* args) {
+    Permset_Object *self = (Permset_Object*) obj;
+
+    if(acl_clear_perms(self->permset) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    /* Return the result */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject* Permset_get_right(PyObject *obj, void* arg) {
+    Permset_Object *self = (Permset_Object*) obj;
+
+    if(get_perm(self->permset, *(acl_perm_t*)arg)) {
+        Py_INCREF(Py_True);
+        return Py_True;
+    } else {
+        Py_INCREF(Py_False);
+        return Py_False;
+    }
+}
+
+static int Permset_set_right(PyObject* obj, PyObject* value, void* arg) {
+    Permset_Object *self = (Permset_Object*) obj;
+    int on;
+    int nerr;
+
+    if(!PyInt_Check(value)) {
+        PyErr_SetString(PyExc_ValueError, "a maximum of one argument must be passed");
+        return -1;
+    }        
+    on = PyInt_AsLong(value);
+    if(on)
+        nerr = acl_add_perm(self->permset, *(acl_perm_t*)arg);
+    else
+        nerr = acl_delete_perm(self->permset, *(acl_perm_t*)arg);
+    if(nerr == -1) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return -1;
+    }
+    return 0;
+}
+
+static char __Permset_add_doc__[] = \
+"Add a permission to the permission set.\n" \
+"\n" \
+"The add() function adds the permission contained in \n" \
+"the argument perm to the permission set.  An attempt \n" \
+"to add a permission that is already contained in the \n" \
+"permission set is not considered an error.\n" \
+"Parameters:\n" \
+"  - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" \
+"Return value:\n" \
+"  None\n" \
+"Can raise: IOError\n" \
+;
+
+static PyObject* Permset_add(PyObject* obj, PyObject* args) {
+    Permset_Object *self = (Permset_Object*) obj;
+    int right;
+
+    if (!PyArg_ParseTuple(args, "i", &right))
+        return NULL;
+
+    if(acl_add_perm(self->permset, (acl_perm_t) right) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    /* Return the result */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static char __Permset_delete_doc__[] = \
+"Delete a permission from the permission set.\n" \
+"\n" \
+"The delete() function deletes the permission contained in \n" \
+"the argument perm from the permission set.  An attempt \n" \
+"to delete a permission that is not contained in the \n" \
+"permission set is not considered an error.\n" \
+"Parameters:\n" \
+"  - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" \
+"Return value:\n" \
+"  None\n" \
+"Can raise: IOError\n" \
+;
+
+static PyObject* Permset_delete(PyObject* obj, PyObject* args) {
+    Permset_Object *self = (Permset_Object*) obj;
+    int right;
+
+    if (!PyArg_ParseTuple(args, "i", &right))
+        return NULL;
+
+    if(acl_delete_perm(self->permset, (acl_perm_t) right) == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    /* Return the result */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static char __Permset_test_doc__[] = \
+"Test if a permission exists in the permission set.\n" \
+"\n" \
+"The test() function tests if the permission contained in \n" \
+"the argument perm exits the permission set.\n" \
+"Parameters:\n" \
+"  - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" \
+"Return value:\n" \
+"  Bool\n" \
+"Can raise: IOError\n" \
+;
+
+static PyObject* Permset_test(PyObject* obj, PyObject* args) {
+    Permset_Object *self = (Permset_Object*) obj;
+    int right;
+    int ret;
+
+    if (!PyArg_ParseTuple(args, "i", &right))
+        return NULL;
+
+    ret = get_perm(self->permset, (acl_perm_t) right);
+    if(ret == -1)
+        return PyErr_SetFromErrno(PyExc_IOError);
+
+    if(ret) {
+        Py_INCREF(Py_True);
+        return Py_True;
+    } else {
+        Py_INCREF(Py_False);
+        return Py_False;
+    }
+}
+
+#endif
+
+static char __ACL_Type_doc__[] = \
+"Type which represents a POSIX ACL\n" \
+"\n" \
+"Parameters:\n" \
+"  Only one keword parameter should be provided:\n"
+"  - file=\"...\", meaning create ACL representing\n"
+"    the access ACL of that file\n" \
+"  - filedef=\"...\", meaning create ACL representing\n"
+"    the default ACL of that directory\n" \
+"  - fd=<int>, meaning create ACL representing\n" \
+"    the access ACL of that file descriptor\n" \
+"  - text=\"...\", meaning create ACL from a \n" \
+"    textual description\n" \
+"  - acl=<ACL instance>, meaning create a copy\n" \
+"    of an existing ACL instance\n" \
+"If no parameters are passed, create an empty ACL; this\n" \
+"makes sense only when your OS supports ACL modification\n" \
+" (i.e. it implements full POSIX.1e support)\n" \
+;
+
+/* ACL type methods */
+static PyMethodDef ACL_methods[] = {
+    {"applyto", ACL_applyto, METH_VARARGS, __applyto_doc__},
+    {"valid", ACL_valid, METH_NOARGS, __valid_doc__},
+#ifdef HAVE_LEVEL2
+    {"__getstate__", ACL_get_state, METH_NOARGS, "Dumps the ACL to an external format."},
+    {"__setstate__", ACL_set_state, METH_VARARGS, "Loads the ACL from an external format."},
+    {"delete_entry", ACL_delete_entry, METH_VARARGS, __ACL_delete_entry_doc__},
+    {"calc_mask", ACL_calc_mask, METH_NOARGS, __ACL_calc_mask_doc__},
+    {"append", ACL_append, METH_VARARGS, __ACL_append_doc__},
+#endif
+    {NULL, NULL, 0, NULL}
+};
+
+
+/* The definition of the ACL Type */
+static PyTypeObject ACL_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "posix1e.ACL",
+    sizeof(ACL_Object),
+    0,
+    ACL_dealloc,        /* tp_dealloc */
+    0,                  /* tp_print */
+    0,                  /* tp_getattr */
+    0,                  /* tp_setattr */
+    0,                  /* tp_compare */
+    0,                  /* tp_repr */
+    0,                  /* tp_as_number */
+    0,                  /* tp_as_sequence */
+    0,                  /* tp_as_mapping */
+    0,                  /* tp_hash */
+    0,                  /* tp_call */
+    ACL_str,            /* tp_str */
+    0,                  /* tp_getattro */
+    0,                  /* tp_setattro */
+    0,                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT, /* tp_flags */
+    __ACL_Type_doc__,   /* tp_doc */
+    0,                  /* tp_traverse */
+    0,                  /* tp_clear */
+    0,                  /* tp_richcompare */
+    0,                  /* tp_weaklistoffset */
+#ifdef HAVE_LEVEL2
+    ACL_iter,
+    ACL_iternext,
+#else
+    0,                  /* tp_iter */
+    0,                  /* tp_iternext */
+#endif
+    ACL_methods,        /* tp_methods */
+    0,                  /* tp_members */
+    0,                  /* tp_getset */
+    0,                  /* tp_base */
+    0,                  /* tp_dict */
+    0,                  /* tp_descr_get */
+    0,                  /* tp_descr_set */
+    0,                  /* tp_dictoffset */
+    ACL_init,           /* tp_init */
+    0,                  /* tp_alloc */
+    ACL_new,            /* tp_new */
+};
+
+#ifdef HAVE_LEVEL2
+
+/* Entry type methods */
+static PyMethodDef Entry_methods[] = {
+    {"copy", Entry_copy, METH_VARARGS, __Entry_copy_doc__},
+    {NULL, NULL, 0, NULL}
+};
+
+static char __Entry_tagtype_doc__[] = \
+"The tag type of the current entry\n" \
+"\n" \
+"This is one of:\n" \
+" - ACL_UNDEFINED_TAG\n" \
+" - ACL_USER_OBJ\n" \
+" - ACL_USER\n" \
+" - ACL_GROUP_OBJ\n" \
+" - ACL_GROUP\n" \
+" - ACL_MASK\n" \
+" - ACL_OTHER\n" \
+;
+
+static char __Entry_qualifier_doc__[] = \
+"The qualifier of the current entry\n" \
+"\n" \
+"If the tag type is ACL_USER, this should be a user id.\n" \
+"If the tag type if ACL_GROUP, this should be a group id.\n" \
+"Else, it doesn't matter.\n" \
+;
+
+static char __Entry_parent_doc__[] = \
+"The parent ACL of this entry\n" \
+;
+
+static char __Entry_permset_doc__[] = \
+"The permission set of this ACL entry\n" \
+;
+
+/* Entry getset */
+static PyGetSetDef Entry_getsets[] = {
+    {"tag_type", Entry_get_tag_type, Entry_set_tag_type, __Entry_tagtype_doc__},
+    {"qualifier", Entry_get_qualifier, Entry_set_qualifier, __Entry_qualifier_doc__},
+    {"parent", Entry_get_parent, NULL, __Entry_parent_doc__},
+    {"permset", Entry_get_permset, Entry_set_permset, __Entry_permset_doc__},
+    {NULL}
+};
+
+static char __Entry_Type_doc__[] = \
+"Type which represents an entry in an ACL.\n" \
+"\n" \
+"The type exists only if the OS has full support for POSIX.1e\n" \
+"Can be created either by:\n" \
+"  e = posix1e.Entry(myACL) # this creates a new entry in the ACL\n" \
+"or by:\n" \
+"  for entry in myACL:\n" \
+"      print entry\n" \
+"\n" \
+"Note that the Entry keeps a reference to its ACL, so even if \n" \
+"you delete the ACL, it won't be cleaned up and will continue to \n" \
+"exist until its Entry(ies) will be deleted.\n" \
+;
+/* The definition of the Entry Type */
+static PyTypeObject Entry_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "posix1e.Entry",
+    sizeof(Entry_Object),
+    0,
+    Entry_dealloc,      /* tp_dealloc */
+    0,                  /* tp_print */
+    0,                  /* tp_getattr */
+    0,                  /* tp_setattr */
+    0,                  /* tp_compare */
+    0,                  /* tp_repr */
+    0,                  /* tp_as_number */
+    0,                  /* tp_as_sequence */
+    0,                  /* tp_as_mapping */
+    0,                  /* tp_hash */
+    0,                  /* tp_call */
+    Entry_str,          /* tp_str */
+    0,                  /* tp_getattro */
+    0,                  /* tp_setattro */
+    0,                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT, /* tp_flags */
+    __Entry_Type_doc__, /* tp_doc */
+    0,                  /* tp_traverse */
+    0,                  /* tp_clear */
+    0,                  /* tp_richcompare */
+    0,                  /* tp_weaklistoffset */
+    0,                  /* tp_iter */
+    0,                  /* tp_iternext */
+    Entry_methods,      /* tp_methods */
+    0,                  /* tp_members */
+    Entry_getsets,      /* tp_getset */
+    0,                  /* tp_base */
+    0,                  /* tp_dict */
+    0,                  /* tp_descr_get */
+    0,                  /* tp_descr_set */
+    0,                  /* tp_dictoffset */
+    Entry_init,         /* tp_init */
+    0,                  /* tp_alloc */
+    Entry_new,          /* tp_new */
+};
+
+/* Permset type methods */
+static PyMethodDef Permset_methods[] = {
+    {"clear", Permset_clear, METH_NOARGS, __Permset_clear_doc__, },
+    {"add", Permset_add, METH_VARARGS, __Permset_add_doc__, },
+    {"delete", Permset_delete, METH_VARARGS, __Permset_delete_doc__, },
+    {"test", Permset_test, METH_VARARGS, __Permset_test_doc__, },
+    {NULL, NULL, 0, NULL}
+};
+
+static char __Permset_execute_doc__[] = \
+"Execute permsission\n" \
+"\n" \
+"This is a convenience method of access; the \n" \
+"same effect can be achieved using the functions\n" \
+"add(), test(), delete(), and those can take any \n" \
+"permission defined by your platform.\n" \
+;
+
+static char __Permset_read_doc__[] = \
+"Read permsission\n" \
+"\n" \
+"This is a convenience method of access; the \n" \
+"same effect can be achieved using the functions\n" \
+"add(), test(), delete(), and those can take any \n" \
+"permission defined by your platform.\n" \
+;
+
+static char __Permset_write_doc__[] = \
+"Write permsission\n" \
+"\n" \
+"This is a convenience method of access; the \n" \
+"same effect can be achieved using the functions\n" \
+"add(), test(), delete(), and those can take any \n" \
+"permission defined by your platform.\n" \
+;
+
+/* Permset getset */
+static PyGetSetDef Permset_getsets[] = {
+    {"execute", Permset_get_right, Permset_set_right, \
+     __Permset_execute_doc__, &holder_ACL_EXECUTE},
+    {"read", Permset_get_right, Permset_set_right, \
+     __Permset_read_doc__, &holder_ACL_READ},
+    {"write", Permset_get_right, Permset_set_right, \
+     __Permset_write_doc__, &holder_ACL_WRITE},
+    {NULL}
+};
+
+static char __Permset_Type_doc__[] = \
+"Type which represents the permission set in an ACL entry\n" \
+"\n" \
+"The type exists only if the OS has full support for POSIX.1e\n" \
+"Can be created either by:\n" \
+"  perms = myEntry.permset\n" \
+"or by:\n" \
+"  perms = posix1e.Permset(myEntry)\n" \
+"\n" \
+"Note that the Permset keeps a reference to its Entry, so even if \n" \
+"you delete the entry, it won't be cleaned up and will continue to \n" \
+"exist until its Permset will be deleted.\n" \
+;
+
+/* The definition of the Permset Type */
+static PyTypeObject Permset_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "posix1e.Permset",
+    sizeof(Permset_Object),
+    0,
+    Permset_dealloc,    /* tp_dealloc */
+    0,                  /* tp_print */
+    0,                  /* tp_getattr */
+    0,                  /* tp_setattr */
+    0,                  /* tp_compare */
+    0,                  /* tp_repr */
+    0,                  /* tp_as_number */
+    0,                  /* tp_as_sequence */
+    0,                  /* tp_as_mapping */
+    0,                  /* tp_hash */
+    0,                  /* tp_call */
+    Permset_str,        /* tp_str */
+    0,                  /* tp_getattro */
+    0,                  /* tp_setattro */
+    0,                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT, /* tp_flags */
+    __Permset_Type_doc__,/* tp_doc */
+    0,                  /* tp_traverse */
+    0,                  /* tp_clear */
+    0,                  /* tp_richcompare */
+    0,                  /* tp_weaklistoffset */
+    0,                  /* tp_iter */
+    0,                  /* tp_iternext */
+    Permset_methods,    /* tp_methods */
+    0,                  /* tp_members */
+    Permset_getsets,    /* tp_getset */
+    0,                  /* tp_base */
+    0,                  /* tp_dict */
+    0,                  /* tp_descr_get */
+    0,                  /* tp_descr_set */
+    0,                  /* tp_dictoffset */
+    Permset_init,       /* tp_init */
+    0,                  /* tp_alloc */
+    Permset_new,        /* tp_new */
+};
+
+#endif
+
+/* Module methods */
+
+static char __deletedef_doc__[] = \
+"Delete the default ACL from a directory.\n" \
+"\n" \
+"This function deletes the default ACL associated with \n" \
+"a directory (the ACL which will be ANDed with the mode\n" \
+"parameter to the open, creat functions).\n" \
+"Parameters:\n" \
+"  - a string representing the directory whose default ACL\n" \
+"    should be deleted\n" \
+;
+
+/* Deletes the default ACL from a directory */
+static PyObject* aclmodule_delete_default(PyObject* obj, PyObject* args) {
+    char *filename;
+
+    /* Parse the arguments */
+    if (!PyArg_ParseTuple(args, "s", &filename))
+        return NULL;
+
+    if(acl_delete_def_file(filename) == -1) {
+        return PyErr_SetFromErrno(PyExc_IOError);
+    }
+
+    /* Return the result */
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/* The module methods */
+static PyMethodDef aclmodule_methods[] = {
+    {"delete_default", aclmodule_delete_default, METH_VARARGS, __deletedef_doc__},
+    {NULL, NULL, 0, NULL}
+};
+
+static char __posix1e_doc__[] = \
+"POSIX.1e ACLs manipulation\n" \
+"\n" \
+"This module provides support for manipulating POSIX.1e ACLS\n" \
+"\n" \
+"Depending on the operating system support for POSIX.1e, \n" \
+"the ACL type will have more or less capabilities:\n" \
+"  - level 1, only basic support, you can create\n" \
+"    ACLs from files and text descriptions;\n" \
+"    once created, the type is immutable\n" \
+"  - level 2, complete support, you can alter\n"\
+"    the ACL once it is created\n" \
+"\n" \
+"Also, in level 2, more types are available, corresponding\n" \
+"to acl_entry_t (Entry type), acl_permset_t (Permset type).\n" \
+"\n" \
+"Example:\n" \
+">>> import posix1e\n" \
+">>> acl1 = posix1e.ACL(file=\"file.txt\") \n" \
+">>> print acl1\n" \
+"user::rw-\n" \
+"group::rw-\n" \
+"other::r--\n" \
+"\n" \
+">>> b = posix1e.ACL(text=\"u::rx,g::-,o::-\")\n" \
+">>> print b\n" \
+"user::r-x\n" \
+"group::---\n" \
+"other::---\n" \
+"\n" \
+">>> b.applyto(\"file.txt\")\n" \
+">>> print posix1e.ACL(file=\"file.txt\")\n" \
+"user::r-x\n" \
+"group::---\n" \
+"other::---\n" \
+"\n" \
+">>>\n" \
+;
+
+void initposix1e(void) {
+    PyObject *m, *d;
+
+    ACL_Type.ob_type = &PyType_Type;
+    if(PyType_Ready(&ACL_Type) < 0)
+        return;
+
+#ifdef HAVE_LEVEL2
+    Entry_Type.ob_type = &PyType_Type;
+    if(PyType_Ready(&Entry_Type) < 0)
+        return;
+
+    Permset_Type.ob_type = &PyType_Type;
+    if(PyType_Ready(&Permset_Type) < 0)
+        return;
+#endif
+
+    m = Py_InitModule3("posix1e", aclmodule_methods, __posix1e_doc__);
+
+    d = PyModule_GetDict(m);
+    if (d == NULL)
+        return;
+
+    Py_INCREF(&ACL_Type);
+    if (PyDict_SetItemString(d, "ACL",
+                             (PyObject *) &ACL_Type) < 0)
+        return;
+
+    /* 23.3.6 acl_type_t values */
+    PyModule_AddIntConstant(m, "ACL_TYPE_ACCESS", ACL_TYPE_ACCESS);
+    PyModule_AddIntConstant(m, "ACL_TYPE_DEFAULT", ACL_TYPE_DEFAULT);
+
+
+#ifdef HAVE_LEVEL2
+    Py_INCREF(&Entry_Type);
+    if (PyDict_SetItemString(d, "Entry",
+                             (PyObject *) &Entry_Type) < 0)
+        return;
+
+    Py_INCREF(&Permset_Type);
+    if (PyDict_SetItemString(d, "Permset",
+                             (PyObject *) &Permset_Type) < 0)
+        return;
+
+    /* 23.2.2 acl_perm_t values */
+    PyModule_AddIntConstant(m, "ACL_READ", ACL_READ);
+    PyModule_AddIntConstant(m, "ACL_WRITE", ACL_WRITE);
+    PyModule_AddIntConstant(m, "ACL_EXECUTE", ACL_EXECUTE);
+
+    /* 23.2.5 acl_tag_t values */
+    PyModule_AddIntConstant(m, "ACL_UNDEFINED_TAG", ACL_UNDEFINED_TAG);
+    PyModule_AddIntConstant(m, "ACL_USER_OBJ", ACL_USER_OBJ);
+    PyModule_AddIntConstant(m, "ACL_USER", ACL_USER);
+    PyModule_AddIntConstant(m, "ACL_GROUP_OBJ", ACL_GROUP_OBJ);
+    PyModule_AddIntConstant(m, "ACL_GROUP", ACL_GROUP);
+    PyModule_AddIntConstant(m, "ACL_MASK", ACL_MASK);
+    PyModule_AddIntConstant(m, "ACL_OTHER", ACL_OTHER);
+
+#endif
+}
diff --git a/os_linux.c b/os_linux.c
new file mode 100644
index 0000000..1fb7203
--- /dev/null
+++ b/os_linux.c
@@ -0,0 +1,6 @@
+#include <acl/libacl.h>
+
+int get_perm(acl_permset_t permset, acl_perm_t perm)
+{
+    return acl_get_perm(permset, perm);
+}
diff --git a/posix1e.html b/posix1e.html
new file mode 100644
index 0000000..9b488ff
--- /dev/null
+++ b/posix1e.html
@@ -0,0 +1,414 @@
+
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><title>Python: module posix1e</title>
+<style type="text/css"><!--
+TT { font-family: lucidatypewriter, lucida console, courier }
+--></style></head><body bgcolor="#f0f0f8">
+
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
+<tr bgcolor="#7799ee">
+<td valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>posix1e</strong></big></big></font></td
+><td align=right valign=bottom
+><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e.so">/home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e.so</a></font></td></tr></table>
+    <p><tt>POSIX.1e&nbsp;ACLs&nbsp;manipulation<br>
+&nbsp;<br>
+This&nbsp;module&nbsp;provides&nbsp;support&nbsp;for&nbsp;manipulating&nbsp;POSIX.1e&nbsp;ACLS<br>
+&nbsp;<br>
+Depending&nbsp;on&nbsp;the&nbsp;operating&nbsp;system&nbsp;support&nbsp;for&nbsp;POSIX.1e,&nbsp;<br>
+the&nbsp;<a href="#ACL">ACL</a>&nbsp;type&nbsp;will&nbsp;have&nbsp;more&nbsp;or&nbsp;less&nbsp;capabilities:<br>
+&nbsp;&nbsp;-&nbsp;level&nbsp;1,&nbsp;only&nbsp;basic&nbsp;support,&nbsp;you&nbsp;can&nbsp;create<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ACLs&nbsp;from&nbsp;files&nbsp;and&nbsp;text&nbsp;descriptions;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;once&nbsp;created,&nbsp;the&nbsp;type&nbsp;is&nbsp;immutable<br>
+&nbsp;&nbsp;-&nbsp;level&nbsp;2,&nbsp;complete&nbsp;support,&nbsp;you&nbsp;can&nbsp;alter<br>
+&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;once&nbsp;it&nbsp;is&nbsp;created<br>
+&nbsp;<br>
+Also,&nbsp;in&nbsp;level&nbsp;2,&nbsp;more&nbsp;types&nbsp;are&nbsp;available,&nbsp;corresponding<br>
+to&nbsp;acl_entry_t&nbsp;(<a href="#Entry">Entry</a>&nbsp;type),&nbsp;acl_permset_t&nbsp;(<a href="#Permset">Permset</a>&nbsp;type).<br>
+&nbsp;<br>
+Example:<br>
+&gt;&gt;&gt;&nbsp;import&nbsp;posix1e<br>
+&gt;&gt;&gt;&nbsp;acl1&nbsp;=&nbsp;posix1e.<a href="#ACL">ACL</a>(file="file.txt")&nbsp;<br>
+&gt;&gt;&gt;&nbsp;print&nbsp;acl1<br>
+user::rw-<br>
+group::rw-<br>
+other::r--<br>
+&nbsp;<br>
+&gt;&gt;&gt;&nbsp;b&nbsp;=&nbsp;posix1e.<a href="#ACL">ACL</a>(text="u::rx,g::-,o::-")<br>
+&gt;&gt;&gt;&nbsp;print&nbsp;b<br>
+user::r-x<br>
+group::---<br>
+other::---<br>
+&nbsp;<br>
+&gt;&gt;&gt;&nbsp;b.applyto("file.txt")<br>
+&gt;&gt;&gt;&nbsp;print&nbsp;posix1e.<a href="#ACL">ACL</a>(file="file.txt")<br>
+user::r-x<br>
+group::---<br>
+other::---<br>
+&nbsp;<br>
+&gt;&gt;&gt;</tt></p>
+
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ee77aa">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
+    
+<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;&nbsp;</td>
+<td width="100%"><dl>
+<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="posix1e.html#ACL">ACL</a>
+</font></dt><dt><font face="helvetica, arial"><a href="posix1e.html#Entry">Entry</a>
+</font></dt><dt><font face="helvetica, arial"><a href="posix1e.html#Permset">Permset</a>
+</font></dt></dl>
+</dd>
+</dl>
+ 
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="ACL">class <strong>ACL</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
+    
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Type&nbsp;which&nbsp;represents&nbsp;a&nbsp;POSIX&nbsp;<a href="#ACL">ACL</a><br>
+&nbsp;<br>
+Parameters:<br>
+&nbsp;&nbsp;Only&nbsp;one&nbsp;keword&nbsp;parameter&nbsp;should&nbsp;be&nbsp;provided:<br>
+&nbsp;&nbsp;-&nbsp;file="...",&nbsp;meaning&nbsp;create&nbsp;<a href="#ACL">ACL</a>&nbsp;representing<br>
+&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;access&nbsp;<a href="#ACL">ACL</a>&nbsp;of&nbsp;that&nbsp;file<br>
+&nbsp;&nbsp;-&nbsp;filedef="...",&nbsp;meaning&nbsp;create&nbsp;<a href="#ACL">ACL</a>&nbsp;representing<br>
+&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;default&nbsp;<a href="#ACL">ACL</a>&nbsp;of&nbsp;that&nbsp;directory<br>
+&nbsp;&nbsp;-&nbsp;fd=&lt;int&gt;,&nbsp;meaning&nbsp;create&nbsp;<a href="#ACL">ACL</a>&nbsp;representing<br>
+&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;access&nbsp;<a href="#ACL">ACL</a>&nbsp;of&nbsp;that&nbsp;file&nbsp;descriptor<br>
+&nbsp;&nbsp;-&nbsp;text="...",&nbsp;meaning&nbsp;create&nbsp;<a href="#ACL">ACL</a>&nbsp;from&nbsp;a&nbsp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;textual&nbsp;description<br>
+&nbsp;&nbsp;-&nbsp;acl=&lt;<a href="#ACL">ACL</a>&nbsp;instance&gt;,&nbsp;meaning&nbsp;create&nbsp;a&nbsp;copy<br>
+&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;an&nbsp;existing&nbsp;<a href="#ACL">ACL</a>&nbsp;instance<br>
+If&nbsp;no&nbsp;parameters&nbsp;are&nbsp;passed,&nbsp;create&nbsp;an&nbsp;empty&nbsp;<a href="#ACL">ACL</a>;&nbsp;this<br>
+makes&nbsp;sense&nbsp;only&nbsp;when&nbsp;your&nbsp;OS&nbsp;supports&nbsp;<a href="#ACL">ACL</a>&nbsp;modification<br>
+&nbsp;(i.e.&nbsp;it&nbsp;implements&nbsp;full&nbsp;POSIX.1e&nbsp;support)<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;&nbsp;</td>
+<td width="100%">Methods defined here:<br>
+<dl><dt><a name="ACL-__getstate__"><strong>__getstate__</strong></a>(...)</dt><dd><tt>Dumps&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;to&nbsp;an&nbsp;external&nbsp;format.</tt></dd></dl>
+
+<dl><dt><a name="ACL-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;x.__class__.__doc__&nbsp;for&nbsp;signature</tt></dd></dl>
+
+<dl><dt><a name="ACL-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
+
+<dl><dt><a name="ACL-__setstate__"><strong>__setstate__</strong></a>(...)</dt><dd><tt>Loads&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;from&nbsp;an&nbsp;external&nbsp;format.</tt></dd></dl>
+
+<dl><dt><a name="ACL-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
+
+<dl><dt><a name="ACL-append"><strong>append</strong></a>(...)</dt><dd><tt>Append&nbsp;a&nbsp;new&nbsp;<a href="#Entry">Entry</a>&nbsp;to&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;and&nbsp;return&nbsp;it.<br>
+&nbsp;<br>
+This&nbsp;is&nbsp;a&nbsp;convenience&nbsp;function&nbsp;to&nbsp;create&nbsp;a&nbsp;new&nbsp;<a href="#Entry">Entry</a>&nbsp;<br>
+and&nbsp;append&nbsp;it&nbsp;to&nbsp;the&nbsp;<a href="#ACL">ACL</a>.<br>
+If&nbsp;a&nbsp;parameter&nbsp;of&nbsp;type&nbsp;<a href="#Entry">Entry</a>&nbsp;instance&nbsp;is&nbsp;given,&nbsp;the&nbsp;<br>
+entry&nbsp;will&nbsp;be&nbsp;a&nbsp;copy&nbsp;of&nbsp;that&nbsp;one&nbsp;(as&nbsp;if&nbsp;copied&nbsp;with&nbsp;<br>
+<a href="#Entry">Entry</a>.copy()),&nbsp;otherwise,&nbsp;the&nbsp;new&nbsp;entry&nbsp;will&nbsp;be&nbsp;empty.</tt></dd></dl>
+
+<dl><dt><a name="ACL-applyto"><strong>applyto</strong></a>(...)</dt><dd><tt>Apply&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;to&nbsp;a&nbsp;file&nbsp;or&nbsp;filehandle.<br>
+&nbsp;<br>
+Parameters:<br>
+&nbsp;&nbsp;-&nbsp;either&nbsp;a&nbsp;filename&nbsp;or&nbsp;a&nbsp;file-like&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;or&nbsp;an&nbsp;integer;&nbsp;this<br>
+&nbsp;&nbsp;&nbsp;&nbsp;represents&nbsp;the&nbsp;filesystem&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;on&nbsp;which&nbsp;to&nbsp;act<br>
+&nbsp;&nbsp;-&nbsp;optional&nbsp;flag&nbsp;representing&nbsp;the&nbsp;type&nbsp;of&nbsp;<a href="#ACL">ACL</a>&nbsp;to&nbsp;set,&nbsp;either<br>
+&nbsp;&nbsp;&nbsp;&nbsp;ACL_TYPE_ACCESS&nbsp;(default)&nbsp;or&nbsp;ACL_TYPE_DEFAULT</tt></dd></dl>
+
+<dl><dt><a name="ACL-calc_mask"><strong>calc_mask</strong></a>(...)</dt><dd><tt>Compute&nbsp;the&nbsp;file&nbsp;group&nbsp;class&nbsp;mask.<br>
+&nbsp;<br>
+The&nbsp;<a href="#ACL-calc_mask">calc_mask</a>()&nbsp;method&nbsp;calculates&nbsp;and&nbsp;sets&nbsp;the&nbsp;permissions&nbsp;<br>
+associated&nbsp;with&nbsp;the&nbsp;ACL_MASK&nbsp;<a href="#Entry">Entry</a>&nbsp;of&nbsp;the&nbsp;<a href="#ACL">ACL</a>.<br>
+The&nbsp;value&nbsp;of&nbsp;the&nbsp;new&nbsp;permissions&nbsp;is&nbsp;the&nbsp;union&nbsp;of&nbsp;the&nbsp;permissions&nbsp;<br>
+granted&nbsp;by&nbsp;all&nbsp;entries&nbsp;of&nbsp;tag&nbsp;type&nbsp;ACL_GROUP,&nbsp;ACL_GROUP_OBJ,&nbsp;or&nbsp;<br>
+ACL_USER.&nbsp;&nbsp;If&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;already&nbsp;contains&nbsp;an&nbsp;ACL_MASK&nbsp;entry,&nbsp;its&nbsp;<br>
+permissions&nbsp;are&nbsp;overwritten;&nbsp;if&nbsp;it&nbsp;does&nbsp;not&nbsp;contain&nbsp;an&nbsp;ACL_MASK&nbsp;<br>
+<a href="#Entry">Entry</a>,&nbsp;one&nbsp;is&nbsp;added.<br>
+&nbsp;<br>
+The&nbsp;order&nbsp;of&nbsp;existing&nbsp;entries&nbsp;in&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;is&nbsp;undefined&nbsp;after&nbsp;this&nbsp;<br>
+function.</tt></dd></dl>
+
+<dl><dt><a name="ACL-delete_entry"><strong>delete_entry</strong></a>(...)</dt><dd><tt>Deletes&nbsp;an&nbsp;entry&nbsp;from&nbsp;the&nbsp;<a href="#ACL">ACL</a>.<br>
+&nbsp;<br>
+Note:&nbsp;Only&nbsp;with&nbsp;level&nbsp;2<br>
+Parameters:<br>
+&nbsp;-&nbsp;the&nbsp;<a href="#Entry">Entry</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;which&nbsp;should&nbsp;be&nbsp;deleted;&nbsp;note&nbsp;that&nbsp;after<br>
+&nbsp;&nbsp;&nbsp;this&nbsp;function&nbsp;is&nbsp;called,&nbsp;that&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;is&nbsp;unusable&nbsp;any&nbsp;longer<br>
+&nbsp;&nbsp;&nbsp;and&nbsp;should&nbsp;be&nbsp;deleted</tt></dd></dl>
+
+<dl><dt><a name="ACL-next"><strong>next</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-next">next</a>()&nbsp;-&gt;&nbsp;the&nbsp;next&nbsp;value,&nbsp;or&nbsp;raise&nbsp;StopIteration</tt></dd></dl>
+
+<dl><dt><a name="ACL-valid"><strong>valid</strong></a>(...)</dt><dd><tt>Test&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;for&nbsp;validity.<br>
+&nbsp;<br>
+This&nbsp;method&nbsp;tests&nbsp;the&nbsp;<a href="#ACL">ACL</a>&nbsp;to&nbsp;see&nbsp;if&nbsp;it&nbsp;is&nbsp;a&nbsp;valid&nbsp;<a href="#ACL">ACL</a><br>
+in&nbsp;terms&nbsp;of&nbsp;the&nbsp;filesystem.&nbsp;More&nbsp;precisely,&nbsp;it&nbsp;checks:<br>
+A&nbsp;valid&nbsp;<a href="#ACL">ACL</a>&nbsp;contains&nbsp;exactly&nbsp;one&nbsp;entry&nbsp;with&nbsp;each&nbsp;of&nbsp;the&nbsp;ACL_USER_OBJ,<br>
+ACL_GROUP_OBJ,&nbsp;and&nbsp;ACL_OTHER&nbsp;tag&nbsp;types.&nbsp;Entries&nbsp;with&nbsp;ACL_USER&nbsp;and<br>
+ACL_GROUP&nbsp;tag&nbsp;types&nbsp;may&nbsp;appear&nbsp;zero&nbsp;or&nbsp;more&nbsp;times&nbsp;in&nbsp;an&nbsp;<a href="#ACL">ACL</a>.&nbsp;An&nbsp;<a href="#ACL">ACL</a>&nbsp;that<br>
+contains&nbsp;entries&nbsp;of&nbsp;ACL_USER&nbsp;or&nbsp;ACL_GROUP&nbsp;tag&nbsp;types&nbsp;must&nbsp;contain&nbsp;exactly<br>
+one&nbsp;entry&nbsp;of&nbsp;the&nbsp;ACL_MASK&nbsp;tag&nbsp;type.&nbsp;If&nbsp;an&nbsp;<a href="#ACL">ACL</a>&nbsp;contains&nbsp;no&nbsp;entries&nbsp;of<br>
+ACL_USER&nbsp;or&nbsp;ACL_GROUP&nbsp;tag&nbsp;types,&nbsp;the&nbsp;ACL_MASK&nbsp;entry&nbsp;is&nbsp;optional.<br>
+&nbsp;<br>
+All&nbsp;user&nbsp;ID&nbsp;qualifiers&nbsp;must&nbsp;be&nbsp;unique&nbsp;among&nbsp;all&nbsp;entries&nbsp;of&nbsp;ACL_USER&nbsp;tag<br>
+type,&nbsp;and&nbsp;all&nbsp;group&nbsp;IDs&nbsp;must&nbsp;be&nbsp;unique&nbsp;among&nbsp;all&nbsp;entries&nbsp;of&nbsp;ACL_GROUP&nbsp;tag<br>
+type.<br>
+&nbsp;<br>
+The&nbsp;method&nbsp;will&nbsp;return&nbsp;1&nbsp;for&nbsp;a&nbsp;valid&nbsp;<a href="#ACL">ACL</a>&nbsp;and&nbsp;0&nbsp;for&nbsp;an&nbsp;invalid&nbsp;one.<br>
+This&nbsp;has&nbsp;been&nbsp;chosen&nbsp;because&nbsp;the&nbsp;specification&nbsp;for&nbsp;acl_valid&nbsp;in&nbsp;POSIX.1e<br>
+documents&nbsp;only&nbsp;one&nbsp;possible&nbsp;value&nbsp;for&nbsp;errno&nbsp;in&nbsp;case&nbsp;of&nbsp;an&nbsp;invalid&nbsp;<a href="#ACL">ACL</a>,&nbsp;<br>
+so&nbsp;we&nbsp;can't&nbsp;differentiate&nbsp;between&nbsp;classes&nbsp;of&nbsp;errors.&nbsp;Other&nbsp;suggestions&nbsp;<br>
+are&nbsp;welcome.</tt></dd></dl>
+
+<hr>
+Data and non-method functions defined here:<br>
+<dl><dt><strong>__doc__</strong> = 'Type which represents a POSIX ACL<font color="#c040c0">\n\n</font>Parameters:<font color="#c040c0">\n</font> ...tion<font color="#c040c0">\n</font> (i.e. it implements full POSIX.1e support)<font color="#c040c0">\n</font>'<dd><tt>str(<a href="__builtin__.html#object">object</a>)&nbsp;-&gt;&nbsp;string<br>
+&nbsp;<br>
+Return&nbsp;a&nbsp;nice&nbsp;string&nbsp;representation&nbsp;of&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>.<br>
+If&nbsp;the&nbsp;argument&nbsp;is&nbsp;a&nbsp;string,&nbsp;the&nbsp;return&nbsp;value&nbsp;is&nbsp;the&nbsp;same&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ACL-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#object">__builtin__.object</a>:<br>
+<dl><dt><a name="ACL-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="ACL-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="ACL-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="ACL-__reduce__"><strong>__reduce__</strong></a>(...)</dt><dd><tt>helper&nbsp;for&nbsp;pickle</tt></dd></dl>
+
+<dl><dt><a name="ACL-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="ACL-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ACL-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<hr>
+Data and non-method functions inherited from <a href="__builtin__.html#object">__builtin__.object</a>:<br>
+<dl><dt><strong>__class__</strong> = &lt;type 'type'&gt;<dd><tt>the&nbsp;<a href="__builtin__.html#object">object</a>'s&nbsp;class</tt></dl>
+
+</td></tr></table> 
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="Entry">class <strong>Entry</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
+    
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Type&nbsp;which&nbsp;represents&nbsp;an&nbsp;entry&nbsp;in&nbsp;an&nbsp;<a href="#ACL">ACL</a>.<br>
+&nbsp;<br>
+The&nbsp;type&nbsp;exists&nbsp;only&nbsp;if&nbsp;the&nbsp;OS&nbsp;has&nbsp;full&nbsp;support&nbsp;for&nbsp;POSIX.1e<br>
+Can&nbsp;be&nbsp;created&nbsp;either&nbsp;by:<br>
+&nbsp;&nbsp;e&nbsp;=&nbsp;posix1e.<a href="#Entry">Entry</a>(myACL)&nbsp;#&nbsp;this&nbsp;creates&nbsp;a&nbsp;new&nbsp;entry&nbsp;in&nbsp;the&nbsp;<a href="#ACL">ACL</a><br>
+or&nbsp;by:<br>
+&nbsp;&nbsp;for&nbsp;entry&nbsp;in&nbsp;myACL:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;entry<br>
+&nbsp;<br>
+Note&nbsp;that&nbsp;the&nbsp;<a href="#Entry">Entry</a>&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;its&nbsp;<a href="#ACL">ACL</a>,&nbsp;so&nbsp;even&nbsp;if&nbsp;<br>
+you&nbsp;delete&nbsp;the&nbsp;<a href="#ACL">ACL</a>,&nbsp;it&nbsp;won't&nbsp;be&nbsp;cleaned&nbsp;up&nbsp;and&nbsp;will&nbsp;continue&nbsp;to&nbsp;<br>
+exist&nbsp;until&nbsp;its&nbsp;<a href="#Entry">Entry</a>(ies)&nbsp;will&nbsp;be&nbsp;deleted.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;&nbsp;</td>
+<td width="100%">Methods defined here:<br>
+<dl><dt><a name="Entry-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#Entry-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;x.__class__.__doc__&nbsp;for&nbsp;signature</tt></dd></dl>
+
+<dl><dt><a name="Entry-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#Entry-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
+
+<dl><dt><a name="Entry-copy"><strong>copy</strong></a>(...)</dt><dd><tt>Copy&nbsp;an&nbsp;<a href="#ACL">ACL</a>&nbsp;entry.<br>
+&nbsp;<br>
+This&nbsp;method&nbsp;sets&nbsp;all&nbsp;the&nbsp;parameters&nbsp;to&nbsp;those&nbsp;of&nbsp;another<br>
+entry,&nbsp;even&nbsp;one&nbsp;of&nbsp;another's&nbsp;<a href="#ACL">ACL</a><br>
+Parameters:<br>
+&nbsp;-&nbsp;src,&nbsp;instance&nbsp;of&nbsp;type&nbsp;<a href="#Entry">Entry</a></tt></dd></dl>
+
+<hr>
+Data and non-method functions defined here:<br>
+<dl><dt><strong>__doc__</strong> = 'Type which represents an entry in an ACL.<font color="#c040c0">\n\n</font>The t... to <font color="#c040c0">\n</font>exist until its Entry(ies) will be deleted.<font color="#c040c0">\n</font>'<dd><tt>str(<a href="__builtin__.html#object">object</a>)&nbsp;-&gt;&nbsp;string<br>
+&nbsp;<br>
+Return&nbsp;a&nbsp;nice&nbsp;string&nbsp;representation&nbsp;of&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>.<br>
+If&nbsp;the&nbsp;argument&nbsp;is&nbsp;a&nbsp;string,&nbsp;the&nbsp;return&nbsp;value&nbsp;is&nbsp;the&nbsp;same&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#Entry-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<dl><dt><strong>parent</strong> = &lt;attribute 'parent' of 'posix1e.Entry' objects&gt;<dd><tt>The&nbsp;parent&nbsp;<a href="#ACL">ACL</a>&nbsp;of&nbsp;this&nbsp;entry</tt></dl>
+
+<dl><dt><strong>permset</strong> = &lt;attribute 'permset' of 'posix1e.Entry' objects&gt;<dd><tt>The&nbsp;permission&nbsp;set&nbsp;of&nbsp;this&nbsp;<a href="#ACL">ACL</a>&nbsp;entry</tt></dl>
+
+<dl><dt><strong>qualifier</strong> = &lt;attribute 'qualifier' of 'posix1e.Entry' objects&gt;<dd><tt>The&nbsp;qualifier&nbsp;of&nbsp;the&nbsp;current&nbsp;entry<br>
+&nbsp;<br>
+If&nbsp;the&nbsp;tag&nbsp;type&nbsp;is&nbsp;ACL_USER,&nbsp;this&nbsp;should&nbsp;be&nbsp;a&nbsp;user&nbsp;id.<br>
+If&nbsp;the&nbsp;tag&nbsp;type&nbsp;if&nbsp;ACL_GROUP,&nbsp;this&nbsp;should&nbsp;be&nbsp;a&nbsp;group&nbsp;id.<br>
+Else,&nbsp;it&nbsp;doesn't&nbsp;matter.</tt></dl>
+
+<dl><dt><strong>tag_type</strong> = &lt;attribute 'tag_type' of 'posix1e.Entry' objects&gt;<dd><tt>The&nbsp;tag&nbsp;type&nbsp;of&nbsp;the&nbsp;current&nbsp;entry<br>
+&nbsp;<br>
+This&nbsp;is&nbsp;one&nbsp;of:<br>
+&nbsp;-&nbsp;ACL_UNDEFINED_TAG<br>
+&nbsp;-&nbsp;ACL_USER_OBJ<br>
+&nbsp;-&nbsp;ACL_USER<br>
+&nbsp;-&nbsp;ACL_GROUP_OBJ<br>
+&nbsp;-&nbsp;ACL_GROUP<br>
+&nbsp;-&nbsp;ACL_MASK<br>
+&nbsp;-&nbsp;ACL_OTHER</tt></dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#object">__builtin__.object</a>:<br>
+<dl><dt><a name="Entry-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Entry-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="Entry-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Entry-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="Entry-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#Entry-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="Entry-__reduce__"><strong>__reduce__</strong></a>(...)</dt><dd><tt>helper&nbsp;for&nbsp;pickle</tt></dd></dl>
+
+<dl><dt><a name="Entry-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#Entry-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="Entry-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Entry-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<hr>
+Data and non-method functions inherited from <a href="__builtin__.html#object">__builtin__.object</a>:<br>
+<dl><dt><strong>__class__</strong> = &lt;type 'type'&gt;<dd><tt>the&nbsp;<a href="__builtin__.html#object">object</a>'s&nbsp;class</tt></dl>
+
+</td></tr></table> 
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="Permset">class <strong>Permset</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
+    
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Type&nbsp;which&nbsp;represents&nbsp;the&nbsp;permission&nbsp;set&nbsp;in&nbsp;an&nbsp;<a href="#ACL">ACL</a>&nbsp;entry<br>
+&nbsp;<br>
+The&nbsp;type&nbsp;exists&nbsp;only&nbsp;if&nbsp;the&nbsp;OS&nbsp;has&nbsp;full&nbsp;support&nbsp;for&nbsp;POSIX.1e<br>
+Can&nbsp;be&nbsp;created&nbsp;either&nbsp;by:<br>
+&nbsp;&nbsp;perms&nbsp;=&nbsp;myEntry.permset<br>
+or&nbsp;by:<br>
+&nbsp;&nbsp;perms&nbsp;=&nbsp;posix1e.<a href="#Permset">Permset</a>(myEntry)<br>
+&nbsp;<br>
+Note&nbsp;that&nbsp;the&nbsp;<a href="#Permset">Permset</a>&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;its&nbsp;<a href="#Entry">Entry</a>,&nbsp;so&nbsp;even&nbsp;if&nbsp;<br>
+you&nbsp;delete&nbsp;the&nbsp;entry,&nbsp;it&nbsp;won't&nbsp;be&nbsp;cleaned&nbsp;up&nbsp;and&nbsp;will&nbsp;continue&nbsp;to&nbsp;<br>
+exist&nbsp;until&nbsp;its&nbsp;<a href="#Permset">Permset</a>&nbsp;will&nbsp;be&nbsp;deleted.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;&nbsp;</td>
+<td width="100%">Methods defined here:<br>
+<dl><dt><a name="Permset-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#Permset-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;x.__class__.__doc__&nbsp;for&nbsp;signature</tt></dd></dl>
+
+<dl><dt><a name="Permset-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#Permset-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
+
+<dl><dt><a name="Permset-add"><strong>add</strong></a>(...)</dt><dd><tt>Add&nbsp;a&nbsp;permission&nbsp;to&nbsp;the&nbsp;permission&nbsp;set.<br>
+&nbsp;<br>
+The&nbsp;<a href="#Permset-add">add</a>()&nbsp;function&nbsp;adds&nbsp;the&nbsp;permission&nbsp;contained&nbsp;in&nbsp;<br>
+the&nbsp;argument&nbsp;perm&nbsp;to&nbsp;the&nbsp;permission&nbsp;set.&nbsp;&nbsp;An&nbsp;attempt&nbsp;<br>
+to&nbsp;add&nbsp;a&nbsp;permission&nbsp;that&nbsp;is&nbsp;already&nbsp;contained&nbsp;in&nbsp;the&nbsp;<br>
+permission&nbsp;set&nbsp;is&nbsp;not&nbsp;considered&nbsp;an&nbsp;error.<br>
+Parameters:<br>
+&nbsp;&nbsp;-&nbsp;perm&nbsp;a&nbsp;permission&nbsp;(ACL_WRITE,&nbsp;ACL_READ,&nbsp;ACL_EXECUTE,&nbsp;...<br>
+Return&nbsp;value:<br>
+&nbsp;&nbsp;None<br>
+Can&nbsp;raise:&nbsp;IOError</tt></dd></dl>
+
+<dl><dt><a name="Permset-clear"><strong>clear</strong></a>(...)</dt><dd><tt>Clear&nbsp;all&nbsp;permissions&nbsp;from&nbsp;the&nbsp;permission&nbsp;set.</tt></dd></dl>
+
+<dl><dt><a name="Permset-delete"><strong>delete</strong></a>(...)</dt><dd><tt>Delete&nbsp;a&nbsp;permission&nbsp;from&nbsp;the&nbsp;permission&nbsp;set.<br>
+&nbsp;<br>
+The&nbsp;<a href="#Permset-delete">delete</a>()&nbsp;function&nbsp;deletes&nbsp;the&nbsp;permission&nbsp;contained&nbsp;in&nbsp;<br>
+the&nbsp;argument&nbsp;perm&nbsp;from&nbsp;the&nbsp;permission&nbsp;set.&nbsp;&nbsp;An&nbsp;attempt&nbsp;<br>
+to&nbsp;delete&nbsp;a&nbsp;permission&nbsp;that&nbsp;is&nbsp;not&nbsp;contained&nbsp;in&nbsp;the&nbsp;<br>
+permission&nbsp;set&nbsp;is&nbsp;not&nbsp;considered&nbsp;an&nbsp;error.<br>
+Parameters:<br>
+&nbsp;&nbsp;-&nbsp;perm&nbsp;a&nbsp;permission&nbsp;(ACL_WRITE,&nbsp;ACL_READ,&nbsp;ACL_EXECUTE,&nbsp;...<br>
+Return&nbsp;value:<br>
+&nbsp;&nbsp;None<br>
+Can&nbsp;raise:&nbsp;IOError</tt></dd></dl>
+
+<dl><dt><a name="Permset-test"><strong>test</strong></a>(...)</dt><dd><tt>Test&nbsp;if&nbsp;a&nbsp;permission&nbsp;exists&nbsp;in&nbsp;the&nbsp;permission&nbsp;set.<br>
+&nbsp;<br>
+The&nbsp;<a href="#Permset-test">test</a>()&nbsp;function&nbsp;tests&nbsp;if&nbsp;the&nbsp;permission&nbsp;contained&nbsp;in&nbsp;<br>
+the&nbsp;argument&nbsp;perm&nbsp;exits&nbsp;the&nbsp;permission&nbsp;set.<br>
+Parameters:<br>
+&nbsp;&nbsp;-&nbsp;perm&nbsp;a&nbsp;permission&nbsp;(ACL_WRITE,&nbsp;ACL_READ,&nbsp;ACL_EXECUTE,&nbsp;...<br>
+Return&nbsp;value:<br>
+&nbsp;&nbsp;Bool<br>
+Can&nbsp;raise:&nbsp;IOError</tt></dd></dl>
+
+<hr>
+Data and non-method functions defined here:<br>
+<dl><dt><strong>__doc__</strong> = 'Type which represents the permission set in an A...nue to <font color="#c040c0">\n</font>exist until its Permset will be deleted.<font color="#c040c0">\n</font>'<dd><tt>str(<a href="__builtin__.html#object">object</a>)&nbsp;-&gt;&nbsp;string<br>
+&nbsp;<br>
+Return&nbsp;a&nbsp;nice&nbsp;string&nbsp;representation&nbsp;of&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>.<br>
+If&nbsp;the&nbsp;argument&nbsp;is&nbsp;a&nbsp;string,&nbsp;the&nbsp;return&nbsp;value&nbsp;is&nbsp;the&nbsp;same&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#Permset-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<dl><dt><strong>execute</strong> = &lt;attribute 'execute' of 'posix1e.Permset' objects&gt;<dd><tt>Execute&nbsp;permsission<br>
+&nbsp;<br>
+This&nbsp;is&nbsp;a&nbsp;convenience&nbsp;method&nbsp;of&nbsp;access;&nbsp;the&nbsp;<br>
+same&nbsp;effect&nbsp;can&nbsp;be&nbsp;achieved&nbsp;using&nbsp;the&nbsp;functions<br>
+<a href="#Permset-add">add</a>(),&nbsp;<a href="#Permset-test">test</a>(),&nbsp;<a href="#Permset-delete">delete</a>(),&nbsp;and&nbsp;those&nbsp;can&nbsp;take&nbsp;any&nbsp;<br>
+permission&nbsp;defined&nbsp;by&nbsp;your&nbsp;platform.</tt></dl>
+
+<dl><dt><strong>read</strong> = &lt;attribute 'read' of 'posix1e.Permset' objects&gt;<dd><tt>Read&nbsp;permsission<br>
+&nbsp;<br>
+This&nbsp;is&nbsp;a&nbsp;convenience&nbsp;method&nbsp;of&nbsp;access;&nbsp;the&nbsp;<br>
+same&nbsp;effect&nbsp;can&nbsp;be&nbsp;achieved&nbsp;using&nbsp;the&nbsp;functions<br>
+<a href="#Permset-add">add</a>(),&nbsp;<a href="#Permset-test">test</a>(),&nbsp;<a href="#Permset-delete">delete</a>(),&nbsp;and&nbsp;those&nbsp;can&nbsp;take&nbsp;any&nbsp;<br>
+permission&nbsp;defined&nbsp;by&nbsp;your&nbsp;platform.</tt></dl>
+
+<dl><dt><strong>write</strong> = &lt;attribute 'write' of 'posix1e.Permset' objects&gt;<dd><tt>Write&nbsp;permsission<br>
+&nbsp;<br>
+This&nbsp;is&nbsp;a&nbsp;convenience&nbsp;method&nbsp;of&nbsp;access;&nbsp;the&nbsp;<br>
+same&nbsp;effect&nbsp;can&nbsp;be&nbsp;achieved&nbsp;using&nbsp;the&nbsp;functions<br>
+<a href="#Permset-add">add</a>(),&nbsp;<a href="#Permset-test">test</a>(),&nbsp;<a href="#Permset-delete">delete</a>(),&nbsp;and&nbsp;those&nbsp;can&nbsp;take&nbsp;any&nbsp;<br>
+permission&nbsp;defined&nbsp;by&nbsp;your&nbsp;platform.</tt></dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#object">__builtin__.object</a>:<br>
+<dl><dt><a name="Permset-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Permset-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="Permset-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Permset-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="Permset-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#Permset-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="Permset-__reduce__"><strong>__reduce__</strong></a>(...)</dt><dd><tt>helper&nbsp;for&nbsp;pickle</tt></dd></dl>
+
+<dl><dt><a name="Permset-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#Permset-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="Permset-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Permset-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<hr>
+Data and non-method functions inherited from <a href="__builtin__.html#object">__builtin__.object</a>:<br>
+<dl><dt><strong>__class__</strong> = &lt;type 'type'&gt;<dd><tt>the&nbsp;<a href="__builtin__.html#object">object</a>'s&nbsp;class</tt></dl>
+
+</td></tr></table></td></tr></table>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#eeaa77">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
+    
+<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;&nbsp;</td>
+<td width="100%"><dl><dt><a name="-delete_default"><strong>delete_default</strong></a>(...)</dt><dd><tt>Delete&nbsp;the&nbsp;default&nbsp;<a href="#ACL">ACL</a>&nbsp;from&nbsp;a&nbsp;directory.<br>
+&nbsp;<br>
+This&nbsp;function&nbsp;deletes&nbsp;the&nbsp;default&nbsp;<a href="#ACL">ACL</a>&nbsp;associated&nbsp;with&nbsp;<br>
+a&nbsp;directory&nbsp;(the&nbsp;<a href="#ACL">ACL</a>&nbsp;which&nbsp;will&nbsp;be&nbsp;ANDed&nbsp;with&nbsp;the&nbsp;mode<br>
+parameter&nbsp;to&nbsp;the&nbsp;open,&nbsp;creat&nbsp;functions).<br>
+Parameters:<br>
+&nbsp;&nbsp;-&nbsp;a&nbsp;string&nbsp;representing&nbsp;the&nbsp;directory&nbsp;whose&nbsp;default&nbsp;<a href="#ACL">ACL</a><br>
+&nbsp;&nbsp;&nbsp;&nbsp;should&nbsp;be&nbsp;deleted</tt></dd></dl>
+</td></tr></table>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#55aa55">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
+    
+<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;&nbsp;</td>
+<td width="100%"><strong>ACL_EXECUTE</strong> = 1<br>
+<strong>ACL_GROUP</strong> = 8<br>
+<strong>ACL_GROUP_OBJ</strong> = 4<br>
+<strong>ACL_MASK</strong> = 16<br>
+<strong>ACL_OTHER</strong> = 32<br>
+<strong>ACL_READ</strong> = 4<br>
+<strong>ACL_TYPE_ACCESS</strong> = 32768<br>
+<strong>ACL_TYPE_DEFAULT</strong> = 16384<br>
+<strong>ACL_UNDEFINED_TAG</strong> = 0<br>
+<strong>ACL_USER</strong> = 2<br>
+<strong>ACL_USER_OBJ</strong> = 1<br>
+<strong>ACL_WRITE</strong> = 2<br>
+<strong>__file__</strong> = '/home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e.so'<br>
+<strong>__name__</strong> = 'posix1e'</td></tr></table>
+</body></html>
\ No newline at end of file
diff --git a/posix1e.txt b/posix1e.txt
new file mode 100644
index 0000000..7657830
--- /dev/null
+++ b/posix1e.txt
@@ -0,0 +1,443 @@
+Python Library Documentation: module posix1e
+
+NAME
+    posix1e - POSIX.1e ACLs manipulation
+
+FILE
+    /home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e.so
+
+DESCRIPTION
+    This module provides support for manipulating POSIX.1e ACLS
+    
+    Depending on the operating system support for POSIX.1e, 
+    the ACL type will have more or less capabilities:
+      - level 1, only basic support, you can create
+        ACLs from files and text descriptions;
+        once created, the type is immutable
+      - level 2, complete support, you can alter
+        the ACL once it is created
+    
+    Also, in level 2, more types are available, corresponding
+    to acl_entry_t (Entry type), acl_permset_t (Permset type).
+    
+    Example:
+    >>> import posix1e
+    >>> acl1 = posix1e.ACL(file="file.txt") 
+    >>> print acl1
+    user::rw-
+    group::rw-
+    other::r--
+    
+    >>> b = posix1e.ACL(text="u::rx,g::-,o::-")
+    >>> print b
+    user::r-x
+    group::---
+    other::---
+    
+    >>> b.applyto("file.txt")
+    >>> print posix1e.ACL(file="file.txt")
+    user::r-x
+    group::---
+    other::---
+    
+    >>>
+
+CLASSES
+    __builtin__.object
+        ACL
+        Entry
+        Permset
+    
+    class ACL(__builtin__.object)
+     |  Type which represents a POSIX ACL
+     |  
+     |  Parameters:
+     |    Only one keword parameter should be provided:
+     |    - file="...", meaning create ACL representing
+     |      the access ACL of that file
+     |    - filedef="...", meaning create ACL representing
+     |      the default ACL of that directory
+     |    - fd=<int>, meaning create ACL representing
+     |      the access ACL of that file descriptor
+     |    - text="...", meaning create ACL from a 
+     |      textual description
+     |    - acl=<ACL instance>, meaning create a copy
+     |      of an existing ACL instance
+     |  If no parameters are passed, create an empty ACL; this
+     |  makes sense only when your OS supports ACL modification
+     |   (i.e. it implements full POSIX.1e support)
+     |  
+     |  Methods defined here:
+     |  
+     |  __getstate__(...)
+     |      Dumps the ACL to an external format.
+     |  
+     |  __init__(...)
+     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+     |  
+     |  __iter__(...)
+     |      x.__iter__() <==> iter(x)
+     |  
+     |  __setstate__(...)
+     |      Loads the ACL from an external format.
+     |  
+     |  __str__(...)
+     |      x.__str__() <==> str(x)
+     |  
+     |  append(...)
+     |      Append a new Entry to the ACL and return it.
+     |      
+     |      This is a convenience function to create a new Entry 
+     |      and append it to the ACL.
+     |      If a parameter of type Entry instance is given, the 
+     |      entry will be a copy of that one (as if copied with 
+     |      Entry.copy()), otherwise, the new entry will be empty.
+     |  
+     |  applyto(...)
+     |      Apply the ACL to a file or filehandle.
+     |      
+     |      Parameters:
+     |        - either a filename or a file-like object or an integer; this
+     |          represents the filesystem object on which to act
+     |        - optional flag representing the type of ACL to set, either
+     |          ACL_TYPE_ACCESS (default) or ACL_TYPE_DEFAULT
+     |  
+     |  calc_mask(...)
+     |      Compute the file group class mask.
+     |      
+     |      The calc_mask() method calculates and sets the permissions 
+     |      associated with the ACL_MASK Entry of the ACL.
+     |      The value of the new permissions is the union of the permissions 
+     |      granted by all entries of tag type ACL_GROUP, ACL_GROUP_OBJ, or 
+     |      ACL_USER.  If the ACL already contains an ACL_MASK entry, its 
+     |      permissions are overwritten; if it does not contain an ACL_MASK 
+     |      Entry, one is added.
+     |      
+     |      The order of existing entries in the ACL is undefined after this 
+     |      function.
+     |  
+     |  delete_entry(...)
+     |      Deletes an entry from the ACL.
+     |      
+     |      Note: Only with level 2
+     |      Parameters:
+     |       - the Entry object which should be deleted; note that after
+     |         this function is called, that object is unusable any longer
+     |         and should be deleted
+     |  
+     |  next(...)
+     |      x.next() -> the next value, or raise StopIteration
+     |  
+     |  valid(...)
+     |      Test the ACL for validity.
+     |      
+     |      This method tests the ACL to see if it is a valid ACL
+     |      in terms of the filesystem. More precisely, it checks:
+     |      A valid ACL contains exactly one entry with each of the ACL_USER_OBJ,
+     |      ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries with ACL_USER and
+     |      ACL_GROUP tag types may appear zero or more times in an ACL. An ACL that
+     |      contains entries of ACL_USER or ACL_GROUP tag types must contain exactly
+     |      one entry of the ACL_MASK tag type. If an ACL contains no entries of
+     |      ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional.
+     |      
+     |      All user ID qualifiers must be unique among all entries of ACL_USER tag
+     |      type, and all group IDs must be unique among all entries of ACL_GROUP tag
+     |      type.
+     |      
+     |      The method will return 1 for a valid ACL and 0 for an invalid one.
+     |      This has been chosen because the specification for acl_valid in POSIX.1e
+     |      documents only one possible value for errno in case of an invalid ACL, 
+     |      so we can't differentiate between classes of errors. Other suggestions 
+     |      are welcome.
+     |  
+     |  ----------------------------------------------------------------------
+     |  Data and non-method functions defined here:
+     |  
+     |  __doc__ = 'Type which represents a POSIX ACL\n\nParameters:\n ...tion\...
+     |      str(object) -> string
+     |      
+     |      Return a nice string representation of the object.
+     |      If the argument is a string, the return value is the same object.
+     |  
+     |  __new__ = <built-in method __new__ of type object>
+     |      T.__new__(S, ...) -> a new object with type S, a subtype of T
+     |  
+     |  ----------------------------------------------------------------------
+     |  Methods inherited from __builtin__.object:
+     |  
+     |  __delattr__(...)
+     |      x.__delattr__('name') <==> del x.name
+     |  
+     |  __getattribute__(...)
+     |      x.__getattribute__('name') <==> x.name
+     |  
+     |  __hash__(...)
+     |      x.__hash__() <==> hash(x)
+     |  
+     |  __reduce__(...)
+     |      helper for pickle
+     |  
+     |  __repr__(...)
+     |      x.__repr__() <==> repr(x)
+     |  
+     |  __setattr__(...)
+     |      x.__setattr__('name', value) <==> x.name = value
+     |  
+     |  ----------------------------------------------------------------------
+     |  Data and non-method functions inherited from __builtin__.object:
+     |  
+     |  __class__ = <type 'type'>
+     |      the object's class
+    
+    class Entry(__builtin__.object)
+     |  Type which represents an entry in an ACL.
+     |  
+     |  The type exists only if the OS has full support for POSIX.1e
+     |  Can be created either by:
+     |    e = posix1e.Entry(myACL) # this creates a new entry in the ACL
+     |  or by:
+     |    for entry in myACL:
+     |        print entry
+     |  
+     |  Note that the Entry keeps a reference to its ACL, so even if 
+     |  you delete the ACL, it won't be cleaned up and will continue to 
+     |  exist until its Entry(ies) will be deleted.
+     |  
+     |  Methods defined here:
+     |  
+     |  __init__(...)
+     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+     |  
+     |  __str__(...)
+     |      x.__str__() <==> str(x)
+     |  
+     |  copy(...)
+     |      Copy an ACL entry.
+     |      
+     |      This method sets all the parameters to those of another
+     |      entry, even one of another's ACL
+     |      Parameters:
+     |       - src, instance of type Entry
+     |  
+     |  ----------------------------------------------------------------------
+     |  Data and non-method functions defined here:
+     |  
+     |  __doc__ = 'Type which represents an entry in an ACL.\n\nThe t... to \n...
+     |      str(object) -> string
+     |      
+     |      Return a nice string representation of the object.
+     |      If the argument is a string, the return value is the same object.
+     |  
+     |  __new__ = <built-in method __new__ of type object>
+     |      T.__new__(S, ...) -> a new object with type S, a subtype of T
+     |  
+     |  parent = <attribute 'parent' of 'posix1e.Entry' objects>
+     |      The parent ACL of this entry
+     |  
+     |  
+     |  permset = <attribute 'permset' of 'posix1e.Entry' objects>
+     |      The permission set of this ACL entry
+     |  
+     |  
+     |  qualifier = <attribute 'qualifier' of 'posix1e.Entry' objects>
+     |      The qualifier of the current entry
+     |      
+     |      If the tag type is ACL_USER, this should be a user id.
+     |      If the tag type if ACL_GROUP, this should be a group id.
+     |      Else, it doesn't matter.
+     |  
+     |  
+     |  tag_type = <attribute 'tag_type' of 'posix1e.Entry' objects>
+     |      The tag type of the current entry
+     |      
+     |      This is one of:
+     |       - ACL_UNDEFINED_TAG
+     |       - ACL_USER_OBJ
+     |       - ACL_USER
+     |       - ACL_GROUP_OBJ
+     |       - ACL_GROUP
+     |       - ACL_MASK
+     |       - ACL_OTHER
+     |  
+     |  
+     |  ----------------------------------------------------------------------
+     |  Methods inherited from __builtin__.object:
+     |  
+     |  __delattr__(...)
+     |      x.__delattr__('name') <==> del x.name
+     |  
+     |  __getattribute__(...)
+     |      x.__getattribute__('name') <==> x.name
+     |  
+     |  __hash__(...)
+     |      x.__hash__() <==> hash(x)
+     |  
+     |  __reduce__(...)
+     |      helper for pickle
+     |  
+     |  __repr__(...)
+     |      x.__repr__() <==> repr(x)
+     |  
+     |  __setattr__(...)
+     |      x.__setattr__('name', value) <==> x.name = value
+     |  
+     |  ----------------------------------------------------------------------
+     |  Data and non-method functions inherited from __builtin__.object:
+     |  
+     |  __class__ = <type 'type'>
+     |      the object's class
+    
+    class Permset(__builtin__.object)
+     |  Type which represents the permission set in an ACL entry
+     |  
+     |  The type exists only if the OS has full support for POSIX.1e
+     |  Can be created either by:
+     |    perms = myEntry.permset
+     |  or by:
+     |    perms = posix1e.Permset(myEntry)
+     |  
+     |  Note that the Permset keeps a reference to its Entry, so even if 
+     |  you delete the entry, it won't be cleaned up and will continue to 
+     |  exist until its Permset will be deleted.
+     |  
+     |  Methods defined here:
+     |  
+     |  __init__(...)
+     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
+     |  
+     |  __str__(...)
+     |      x.__str__() <==> str(x)
+     |  
+     |  add(...)
+     |      Add a permission to the permission set.
+     |      
+     |      The add() function adds the permission contained in 
+     |      the argument perm to the permission set.  An attempt 
+     |      to add a permission that is already contained in the 
+     |      permission set is not considered an error.
+     |      Parameters:
+     |        - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...
+     |      Return value:
+     |        None
+     |      Can raise: IOError
+     |  
+     |  clear(...)
+     |      Clear all permissions from the permission set.
+     |  
+     |  delete(...)
+     |      Delete a permission from the permission set.
+     |      
+     |      The delete() function deletes the permission contained in 
+     |      the argument perm from the permission set.  An attempt 
+     |      to delete a permission that is not contained in the 
+     |      permission set is not considered an error.
+     |      Parameters:
+     |        - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...
+     |      Return value:
+     |        None
+     |      Can raise: IOError
+     |  
+     |  test(...)
+     |      Test if a permission exists in the permission set.
+     |      
+     |      The test() function tests if the permission contained in 
+     |      the argument perm exits the permission set.
+     |      Parameters:
+     |        - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...
+     |      Return value:
+     |        Bool
+     |      Can raise: IOError
+     |  
+     |  ----------------------------------------------------------------------
+     |  Data and non-method functions defined here:
+     |  
+     |  __doc__ = 'Type which represents the permission set in an A...nue to \...
+     |      str(object) -> string
+     |      
+     |      Return a nice string representation of the object.
+     |      If the argument is a string, the return value is the same object.
+     |  
+     |  __new__ = <built-in method __new__ of type object>
+     |      T.__new__(S, ...) -> a new object with type S, a subtype of T
+     |  
+     |  execute = <attribute 'execute' of 'posix1e.Permset' objects>
+     |      Execute permsission
+     |      
+     |      This is a convenience method of access; the 
+     |      same effect can be achieved using the functions
+     |      add(), test(), delete(), and those can take any 
+     |      permission defined by your platform.
+     |  
+     |  
+     |  read = <attribute 'read' of 'posix1e.Permset' objects>
+     |      Read permsission
+     |      
+     |      This is a convenience method of access; the 
+     |      same effect can be achieved using the functions
+     |      add(), test(), delete(), and those can take any 
+     |      permission defined by your platform.
+     |  
+     |  
+     |  write = <attribute 'write' of 'posix1e.Permset' objects>
+     |      Write permsission
+     |      
+     |      This is a convenience method of access; the 
+     |      same effect can be achieved using the functions
+     |      add(), test(), delete(), and those can take any 
+     |      permission defined by your platform.
+     |  
+     |  
+     |  ----------------------------------------------------------------------
+     |  Methods inherited from __builtin__.object:
+     |  
+     |  __delattr__(...)
+     |      x.__delattr__('name') <==> del x.name
+     |  
+     |  __getattribute__(...)
+     |      x.__getattribute__('name') <==> x.name
+     |  
+     |  __hash__(...)
+     |      x.__hash__() <==> hash(x)
+     |  
+     |  __reduce__(...)
+     |      helper for pickle
+     |  
+     |  __repr__(...)
+     |      x.__repr__() <==> repr(x)
+     |  
+     |  __setattr__(...)
+     |      x.__setattr__('name', value) <==> x.name = value
+     |  
+     |  ----------------------------------------------------------------------
+     |  Data and non-method functions inherited from __builtin__.object:
+     |  
+     |  __class__ = <type 'type'>
+     |      the object's class
+
+FUNCTIONS
+    delete_default(...)
+        Delete the default ACL from a directory.
+        
+        This function deletes the default ACL associated with 
+        a directory (the ACL which will be ANDed with the mode
+        parameter to the open, creat functions).
+        Parameters:
+          - a string representing the directory whose default ACL
+            should be deleted
+
+DATA
+    ACL_EXECUTE = 1
+    ACL_GROUP = 8
+    ACL_GROUP_OBJ = 4
+    ACL_MASK = 16
+    ACL_OTHER = 32
+    ACL_READ = 4
+    ACL_TYPE_ACCESS = 32768
+    ACL_TYPE_DEFAULT = 16384
+    ACL_UNDEFINED_TAG = 0
+    ACL_USER = 2
+    ACL_USER_OBJ = 1
+    ACL_WRITE = 2
+    __file__ = '/home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e...
+    __name__ = 'posix1e'
+
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..f8c1ed7
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,4 @@
+[bdist_rpm]
+release = 1
+requires = libacl
+;build_requires = libacl libacl-devel
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..95231f8
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+import distutils, os
+from distutils.core import setup, Extension
+
+(u_sysname, u_nodename, u_release, u_version, u_machine) = os.uname()
+
+macros = []
+libs = []
+if u_sysname == "Linux":
+    macros.append(("HAVE_LINUX", None))
+    macros.append(("HAVE_LEVEL2", None))
+    libs.append("acl")
+elif u_sysname == "GNU/kFreeBSD":
+    macros.append(("HAVE_LINUX", None))
+    macros.append(("HAVE_LEVEL2", None))
+    libs.append("acl")
+elif u_sysname == "FreeBSD":
+    macros.append(("HAVE_FREEBSD", None))
+else:
+    raise ValueError("I don't know your system '%s'."
+                     " Please contact the author" % u_sysname)
+
+long_desc = """This is a C extension module for Python which
+implements POSIX ACLs manipulation. It is a wrapper on top
+of the systems's acl C library - see acl(5)."""
+version = "0.2.2"
+setup(name="pylibacl",
+      version=version,
+      description="POSIX.1e ACLs for python",
+      long_description=long_desc,
+      author="Iustin Pop",
+      author_email="iusty@k1024.org",
+      url="http://pylibacl.sourceforge.net",
+      license="GPL",
+      ext_modules=[Extension("posix1e", ["acl.c"],
+                             libraries=libs,
+                             define_macros=macros,
+                             )],
+      data_files=[("/usr/share/doc/pylibacl-%s" % version,
+                   ["README","IMPLEMENTATION", "PLATFORMS",
+                    "BENCHMARK",
+                    "posix1e.html", "posix1e.txt"])],
+      )
-- 
2.39.5