implémenter une fonction python dans un module ecrit en C
13 réponses
Thomas Harding
Bonjour,
Ayant été confronté à des problème d'erreur de segmentation sur une
Mandrake 9.2 lors de l'extraction des acls, j'ai modifié le module
python pylibacl pour utiliser la fonction acl_to_any_text de la
libacl, en passant l'option TEXT_NUMERIC_IDS, à la place de la fonction
acl_to_text.
(le programme python plantait -- erreur de segmentation -- lorsqu'un
utilisateur/groupe ne pouvait être trouvé par getent)
Je pense qu'il serait utile, au lieu de modifier la fonction str du
module python, d'ajouter une fonction "strnum", ou quelque autre nom
que ce soit.
Exemple d'application: extraction des acls sur système pour replacage
sur un autre système 'en attente', sans résolution de noms (genre Samba
arrêté).
Le problème est que je n'ai aucune compétence en C (à part quelques
rares hacks très simples), et encore moins dans l'implémentation de
modules python écrits en C :/
Bref, si quelqu'un a le temps et l'envie de le faire, ou alors la
patience de me faire de longues explications sur l'implémentation
de modules pytho en C, je suis preneur :)
/* 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;
/* 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;
/* 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;
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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
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, (int)arg);
else
nerr = acl_delete_perm(self->permset, (int)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" \
;
/* 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" \
;
/* 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);
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}
};
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" \
;
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" \
;
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" \
;
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;
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" \
;
Bonjour, Ayant été confronté à des problème d'erreur de segmentation sur une Mandrake 9.2 lors de l'extraction des acls, j'ai modifié le module python pylibacl pour utiliser la fonction acl_to_any_text de la libacl, en passant l'option TEXT_NUMERIC_IDS, à la place de la fonction acl_to_text.
(le programme python plantait -- erreur de segmentation -- lorsqu'un utilisateur/groupe ne pouvait être trouvé par getent)
Je pense qu'il serait utile, au lieu de modifier la fonction str du module python, d'ajouter une fonction "strnum", ou quelque autre nom que ce soit.
Exemple d'application: extraction des acls sur système pour replacage sur un autre système 'en attente', sans résolution de noms (genre Samba arrêté).
Le problème est que je n'ai aucune compétence en C (à part quelques rares hacks très simples), et encore moins dans l'implémentation de modules python écrits en C :/
Bref, si quelqu'un a le temps et l'envie de le faire, ou alors la patience de me faire de longues explications sur l'implémentation de modules pytho en C, je suis preneur :)
/* 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; thisn" " represents the filesystem object on which to actn" " - optional flag representing the type of ACL to set, eithern" " ACL_TYPE_ACCESS (default) or ACL_TYPE_DEFAULTn" ;
/* 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;
/* 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 ACLn" "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 andn" "ACL_GROUP tag types may appear zero or more times in an ACL. An ACL thatn" "contains entries of ACL_USER or ACL_GROUP tag types must contain exactlyn" "one entry of the ACL_MASK tag type. If an ACL contains no entries ofn" "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 tagn" "type, and all group IDs must be unique among all entries of ACL_GROUP tagn" "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.1en" "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;
/* 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;
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 2n" "Parameters:n" " - the Entry object which should be deleted; note that aftern" " this function is called, that object is unusable any longern" " and should be deletedn" ;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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 anothern" "entry, even one of another's ACLn" "Parameters:n" " - src, instance of type Entryn" ;
/* 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;
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, (int)arg); else nerr = acl_delete_perm(self->permset, (int)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" " Nonen" "Can raise: IOErrorn" ;
/* 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" " Nonen" "Can raise: IOErrorn" ;
/* 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" " Booln" "Can raise: IOErrorn" ;
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);
static char __ACL_Type_doc__[] = "Type which represents a POSIX ACLn" "n" "Parameters:n" " Only one keword parameter should be provided:n" " - file="...", meaning create ACL representingn" " the access ACL of that filen" " - filedef="...", meaning create ACL representingn" " the default ACL of that directoryn" " - fd=<int>, meaning create ACL representingn" " the access ACL of that file descriptorn" " - text="...", meaning create ACL from a n" " textual descriptionn" " - acl=<ACL instance>, meaning create a copyn" " of an existing ACL instancen" "If no parameters are passed, create an empty ACL; thisn" "makes sense only when your OS supports ACL modificationn" " (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} };
static char __Entry_tagtype_doc__[] = "The tag type of the current entryn" "n" "This is one of:n" " - ACL_UNDEFINED_TAGn" " - ACL_USER_OBJn" " - ACL_USERn" " - ACL_GROUP_OBJn" " - ACL_GROUPn" " - ACL_MASKn" " - ACL_OTHERn" ;
static char __Entry_qualifier_doc__[] = "The qualifier of the current entryn" "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 entryn" ;
static char __Entry_permset_doc__[] = "The permission set of this ACL entryn" ;
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.1en" "Can be created either by:n" " e = posix1e.Entry(myACL) # this creates a new entry in the ACLn" "or by:n" " for entry in myACL:n" " print entryn" "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 */ };
static char __Permset_execute_doc__[] = "Execute permsissionn" "n" "This is a convenience method of access; the n" "same effect can be achieved using the functionsn" "add(), test(), delete(), and those can take any n" "permission defined by your platform.n" ;
static char __Permset_read_doc__[] = "Read permsissionn" "n" "This is a convenience method of access; the n" "same effect can be achieved using the functionsn" "add(), test(), delete(), and those can take any n" "permission defined by your platform.n" ;
static char __Permset_write_doc__[] = "Write permsissionn" "n" "This is a convenience method of access; the n" "same effect can be achieved using the functionsn" "add(), test(), delete(), and those can take any n" "permission defined by your platform.n" ;
static char __Permset_Type_doc__[] = "Type which represents the permission set in an ACL entryn" "n" "The type exists only if the OS has full support for POSIX.1en" "Can be created either by:n" " perms = myEntry.permsetn" "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" ;
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 moden" "parameter to the open, creat functions).n" "Parameters:n" " - a string representing the directory whose default ACLn" " should be deletedn" ;
/* 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;
static char __posix1e_doc__[] = "POSIX.1e ACLs manipulationn" "n" "This module provides support for manipulating POSIX.1e ACLSn" "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 createn" " ACLs from files and text descriptions;n" " once created, the type is immutablen" " - level 2, complete support, you can altern" " the ACL once it is createdn" "n" "Also, in level 2, more types are available, correspondingn" "to acl_entry_t (Entry type), acl_permset_t (Permset type).n" "n" "Example:n" ">>> import posix1en" ">>> acl1 = posix1e.ACL(file="file.txt") n" ">>> print acl1n" "user::rw-n" "group::rw-n" "other::r--n" "n" ">>> b = posix1e.ACL(text="u::rx,g::-,o::-")n" ">>> print bn" "user::r-xn" "group::---n" "other::---n" "n" ">>> b.applyto("file.txt")n" ">>> print posix1e.ACL(file="file.txt")n" "user::r-xn" "group::---n" "other::---n" "n" ">>>n" ;
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour accéder à la librairie acl ?
hg
Thomas Harding wrote:
Bonjour,
Ayant été confronté à des problème d'erreur de segmentation sur une
Mandrake 9.2 lors de l'extraction des acls, j'ai modifié le module
python pylibacl pour utiliser la fonction acl_to_any_text de la
libacl, en passant l'option TEXT_NUMERIC_IDS, à la place de la fonction
acl_to_text.
(le programme python plantait -- erreur de segmentation -- lorsqu'un
utilisateur/groupe ne pouvait être trouvé par getent)
Je pense qu'il serait utile, au lieu de modifier la fonction str du
module python, d'ajouter une fonction "strnum", ou quelque autre nom
que ce soit.
Exemple d'application: extraction des acls sur système pour replacage
sur un autre système 'en attente', sans résolution de noms (genre Samba
arrêté).
Le problème est que je n'ai aucune compétence en C (à part quelques
rares hacks très simples), et encore moins dans l'implémentation de
modules python écrits en C :/
Bref, si quelqu'un a le temps et l'envie de le faire, ou alors la
patience de me faire de longues explications sur l'implémentation
de modules pytho en C, je suis preneur :)
/* 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; thisn"
" represents the filesystem object on which to actn"
" - optional flag representing the type of ACL to set, eithern"
" ACL_TYPE_ACCESS (default) or ACL_TYPE_DEFAULTn"
;
/* 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;
/* 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 ACLn"
"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 andn"
"ACL_GROUP tag types may appear zero or more times in an ACL. An ACL
thatn" "contains entries of ACL_USER or ACL_GROUP tag types must
contain exactlyn" "one entry of the ACL_MASK tag type. If an ACL
contains no entries ofn" "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
tagn" "type, and all group IDs must be unique among all entries of
ACL_GROUP tagn" "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.1en" "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;
/* 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;
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 2n"
"Parameters:n"
" - the Entry object which should be deleted; note that aftern"
" this function is called, that object is unusable any longern"
" and should be deletedn"
;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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 anothern"
"entry, even one of another's ACLn"
"Parameters:n"
" - src, instance of type Entryn"
;
/* 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;
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, (int)arg);
else
nerr = acl_delete_perm(self->permset, (int)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"
" Nonen"
"Can raise: IOErrorn"
;
/* 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"
" Nonen"
"Can raise: IOErrorn"
;
/* 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"
" Booln"
"Can raise: IOErrorn"
;
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);
static char __ACL_Type_doc__[] =
"Type which represents a POSIX ACLn"
"n"
"Parameters:n"
" Only one keword parameter should be provided:n"
" - file="...", meaning create ACL representingn"
" the access ACL of that filen"
" - filedef="...", meaning create ACL representingn"
" the default ACL of that directoryn"
" - fd=<int>, meaning create ACL representingn"
" the access ACL of that file descriptorn"
" - text="...", meaning create ACL from a n"
" textual descriptionn"
" - acl=<ACL instance>, meaning create a copyn"
" of an existing ACL instancen"
"If no parameters are passed, create an empty ACL; thisn"
"makes sense only when your OS supports ACL modificationn"
" (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}
};
static char __Entry_tagtype_doc__[] =
"The tag type of the current entryn"
"n"
"This is one of:n"
" - ACL_UNDEFINED_TAGn"
" - ACL_USER_OBJn"
" - ACL_USERn"
" - ACL_GROUP_OBJn"
" - ACL_GROUPn"
" - ACL_MASKn"
" - ACL_OTHERn"
;
static char __Entry_qualifier_doc__[] =
"The qualifier of the current entryn"
"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 entryn"
;
static char __Entry_permset_doc__[] =
"The permission set of this ACL entryn"
;
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.1en"
"Can be created either by:n"
" e = posix1e.Entry(myACL) # this creates a new entry in the ACLn"
"or by:n"
" for entry in myACL:n"
" print entryn"
"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 */
};
static char __Permset_execute_doc__[] =
"Execute permsissionn"
"n"
"This is a convenience method of access; the n"
"same effect can be achieved using the functionsn"
"add(), test(), delete(), and those can take any n"
"permission defined by your platform.n"
;
static char __Permset_read_doc__[] =
"Read permsissionn"
"n"
"This is a convenience method of access; the n"
"same effect can be achieved using the functionsn"
"add(), test(), delete(), and those can take any n"
"permission defined by your platform.n"
;
static char __Permset_write_doc__[] =
"Write permsissionn"
"n"
"This is a convenience method of access; the n"
"same effect can be achieved using the functionsn"
"add(), test(), delete(), and those can take any n"
"permission defined by your platform.n"
;
static char __Permset_Type_doc__[] =
"Type which represents the permission set in an ACL entryn"
"n"
"The type exists only if the OS has full support for POSIX.1en"
"Can be created either by:n"
" perms = myEntry.permsetn"
"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"
;
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 moden"
"parameter to the open, creat functions).n"
"Parameters:n"
" - a string representing the directory whose default ACLn"
" should be deletedn"
;
/* 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;
static char __posix1e_doc__[] =
"POSIX.1e ACLs manipulationn"
"n"
"This module provides support for manipulating POSIX.1e ACLSn"
"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 createn"
" ACLs from files and text descriptions;n"
" once created, the type is immutablen"
" - level 2, complete support, you can altern"
" the ACL once it is createdn"
"n"
"Also, in level 2, more types are available, correspondingn"
"to acl_entry_t (Entry type), acl_permset_t (Permset type).n"
"n"
"Example:n"
">>> import posix1en"
">>> acl1 = posix1e.ACL(file="file.txt") n"
">>> print acl1n"
"user::rw-n"
"group::rw-n"
"other::r--n"
"n"
">>> b = posix1e.ACL(text="u::rx,g::-,o::-")n"
">>> print bn"
"user::r-xn"
"group::---n"
"other::---n"
"n"
">>> b.applyto("file.txt")n"
">>> print posix1e.ACL(file="file.txt")n"
"user::r-xn"
"group::---n"
"other::---n"
"n"
">>>n"
;
Bonjour, Ayant été confronté à des problème d'erreur de segmentation sur une Mandrake 9.2 lors de l'extraction des acls, j'ai modifié le module python pylibacl pour utiliser la fonction acl_to_any_text de la libacl, en passant l'option TEXT_NUMERIC_IDS, à la place de la fonction acl_to_text.
(le programme python plantait -- erreur de segmentation -- lorsqu'un utilisateur/groupe ne pouvait être trouvé par getent)
Je pense qu'il serait utile, au lieu de modifier la fonction str du module python, d'ajouter une fonction "strnum", ou quelque autre nom que ce soit.
Exemple d'application: extraction des acls sur système pour replacage sur un autre système 'en attente', sans résolution de noms (genre Samba arrêté).
Le problème est que je n'ai aucune compétence en C (à part quelques rares hacks très simples), et encore moins dans l'implémentation de modules python écrits en C :/
Bref, si quelqu'un a le temps et l'envie de le faire, ou alors la patience de me faire de longues explications sur l'implémentation de modules pytho en C, je suis preneur :)
/* 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; thisn" " represents the filesystem object on which to actn" " - optional flag representing the type of ACL to set, eithern" " ACL_TYPE_ACCESS (default) or ACL_TYPE_DEFAULTn" ;
/* 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;
/* 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 ACLn" "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 andn" "ACL_GROUP tag types may appear zero or more times in an ACL. An ACL thatn" "contains entries of ACL_USER or ACL_GROUP tag types must contain exactlyn" "one entry of the ACL_MASK tag type. If an ACL contains no entries ofn" "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 tagn" "type, and all group IDs must be unique among all entries of ACL_GROUP tagn" "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.1en" "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;
/* 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;
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 2n" "Parameters:n" " - the Entry object which should be deleted; note that aftern" " this function is called, that object is unusable any longern" " and should be deletedn" ;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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;
/* 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 anothern" "entry, even one of another's ACLn" "Parameters:n" " - src, instance of type Entryn" ;
/* 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;
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, (int)arg); else nerr = acl_delete_perm(self->permset, (int)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" " Nonen" "Can raise: IOErrorn" ;
/* 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" " Nonen" "Can raise: IOErrorn" ;
/* 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" " Booln" "Can raise: IOErrorn" ;
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);
static char __ACL_Type_doc__[] = "Type which represents a POSIX ACLn" "n" "Parameters:n" " Only one keword parameter should be provided:n" " - file="...", meaning create ACL representingn" " the access ACL of that filen" " - filedef="...", meaning create ACL representingn" " the default ACL of that directoryn" " - fd=<int>, meaning create ACL representingn" " the access ACL of that file descriptorn" " - text="...", meaning create ACL from a n" " textual descriptionn" " - acl=<ACL instance>, meaning create a copyn" " of an existing ACL instancen" "If no parameters are passed, create an empty ACL; thisn" "makes sense only when your OS supports ACL modificationn" " (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} };
static char __Entry_tagtype_doc__[] = "The tag type of the current entryn" "n" "This is one of:n" " - ACL_UNDEFINED_TAGn" " - ACL_USER_OBJn" " - ACL_USERn" " - ACL_GROUP_OBJn" " - ACL_GROUPn" " - ACL_MASKn" " - ACL_OTHERn" ;
static char __Entry_qualifier_doc__[] = "The qualifier of the current entryn" "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 entryn" ;
static char __Entry_permset_doc__[] = "The permission set of this ACL entryn" ;
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.1en" "Can be created either by:n" " e = posix1e.Entry(myACL) # this creates a new entry in the ACLn" "or by:n" " for entry in myACL:n" " print entryn" "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 */ };
static char __Permset_execute_doc__[] = "Execute permsissionn" "n" "This is a convenience method of access; the n" "same effect can be achieved using the functionsn" "add(), test(), delete(), and those can take any n" "permission defined by your platform.n" ;
static char __Permset_read_doc__[] = "Read permsissionn" "n" "This is a convenience method of access; the n" "same effect can be achieved using the functionsn" "add(), test(), delete(), and those can take any n" "permission defined by your platform.n" ;
static char __Permset_write_doc__[] = "Write permsissionn" "n" "This is a convenience method of access; the n" "same effect can be achieved using the functionsn" "add(), test(), delete(), and those can take any n" "permission defined by your platform.n" ;
static char __Permset_Type_doc__[] = "Type which represents the permission set in an ACL entryn" "n" "The type exists only if the OS has full support for POSIX.1en" "Can be created either by:n" " perms = myEntry.permsetn" "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" ;
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 moden" "parameter to the open, creat functions).n" "Parameters:n" " - a string representing the directory whose default ACLn" " should be deletedn" ;
/* 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;
static char __posix1e_doc__[] = "POSIX.1e ACLs manipulationn" "n" "This module provides support for manipulating POSIX.1e ACLSn" "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 createn" " ACLs from files and text descriptions;n" " once created, the type is immutablen" " - level 2, complete support, you can altern" " the ACL once it is createdn" "n" "Also, in level 2, more types are available, correspondingn" "to acl_entry_t (Entry type), acl_permset_t (Permset type).n" "n" "Example:n" ">>> import posix1en" ">>> acl1 = posix1e.ACL(file="file.txt") n" ">>> print acl1n" "user::rw-n" "group::rw-n" "other::r--n" "n" ">>> b = posix1e.ACL(text="u::rx,g::-,o::-")n" ">>> print bn" "user::r-xn" "group::---n" "other::---n" "n" ">>> b.applyto("file.txt")n" ">>> print posix1e.ACL(file="file.txt")n" "user::r-xn" "group::---n" "other::---n" "n" ">>>n" ;
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour accéder à la librairie acl ?
hg
Thomas Harding
Le 08-07-2007, hg a écrit :
Thomas Harding wrote:
Bonjour, Ayant été confronté à des problème d'erreur de segmentation sur une Mandrake 9.2 lors de l'extraction des acls, j'ai modifié le module python pylibacl pour utiliser la fonction acl_to_any_text de la libacl, en passant l'option TEXT_NUMERIC_IDS, à la place de la fonction acl_to_text.
(le programme python plantait -- erreur de segmentation -- lorsqu'un utilisateur/groupe ne pouvait être trouvé par getent)
Je pense qu'il serait utile, au lieu de modifier la fonction str du module python, d'ajouter une fonction "strnum", ou quelque autre nom que ce soit.
Bonjour,
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour accéder à la librairie acl ?
Ben, heu: - parce que l'extension existe - parce que je ne connais pas ctypes (je suis relativement nouveau en python, j'ai surtout fait du bash et du php avant ces deux derniers mois).
Je vais voir de quoi il retourne...
-- Thomas Harding
Le 08-07-2007, hg <hg@nospam.org> a écrit :
Thomas Harding wrote:
Bonjour,
Ayant été confronté à des problème d'erreur de segmentation sur une
Mandrake 9.2 lors de l'extraction des acls, j'ai modifié le module
python pylibacl pour utiliser la fonction acl_to_any_text de la
libacl, en passant l'option TEXT_NUMERIC_IDS, à la place de la fonction
acl_to_text.
(le programme python plantait -- erreur de segmentation -- lorsqu'un
utilisateur/groupe ne pouvait être trouvé par getent)
Je pense qu'il serait utile, au lieu de modifier la fonction str du
module python, d'ajouter une fonction "strnum", ou quelque autre nom
que ce soit.
Bonjour,
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour
accéder à la librairie acl ?
Ben, heu:
- parce que l'extension existe
- parce que je ne connais pas ctypes (je suis relativement nouveau en
python, j'ai surtout fait du bash et du php avant ces deux derniers
mois).
Bonjour, Ayant été confronté à des problème d'erreur de segmentation sur une Mandrake 9.2 lors de l'extraction des acls, j'ai modifié le module python pylibacl pour utiliser la fonction acl_to_any_text de la libacl, en passant l'option TEXT_NUMERIC_IDS, à la place de la fonction acl_to_text.
(le programme python plantait -- erreur de segmentation -- lorsqu'un utilisateur/groupe ne pouvait être trouvé par getent)
Je pense qu'il serait utile, au lieu de modifier la fonction str du module python, d'ajouter une fonction "strnum", ou quelque autre nom que ce soit.
Bonjour,
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour accéder à la librairie acl ?
Ben, heu: - parce que l'extension existe - parce que je ne connais pas ctypes (je suis relativement nouveau en python, j'ai surtout fait du bash et du php avant ces deux derniers mois).
Je vais voir de quoi il retourne...
-- Thomas Harding
Thomas Harding
Le 08-07-2007, Thomas Harding a écrit :
Je pense qu'il serait utile, au lieu de modifier la fonction str du module python, d'ajouter une fonction "strnum", ou quelque autre nom que ce soit.
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour accéder à la librairie acl ?
Ben, heu: - parce que l'extension existe - parce que je ne connais pas ctypes (je suis relativement nouveau en python, j'ai surtout fait du bash et du php avant ces deux derniers mois).
Je vais voir de quoi il retourne...
- parce que j'ai lu le tutoriel de ctypes et que je n'y ai pas compris grand-chose :). Apparemment, il faut aussi avoir de solides notions de C...
-- Thomas Harding
Le 08-07-2007, Thomas Harding <thomas.harding@laposte.net> a écrit :
Je pense qu'il serait utile, au lieu de modifier la fonction str du
module python, d'ajouter une fonction "strnum", ou quelque autre nom
que ce soit.
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour
accéder à la librairie acl ?
Ben, heu:
- parce que l'extension existe
- parce que je ne connais pas ctypes (je suis relativement nouveau en
python, j'ai surtout fait du bash et du php avant ces deux derniers
mois).
Je vais voir de quoi il retourne...
- parce que j'ai lu le tutoriel de ctypes et que je n'y ai pas compris
grand-chose :). Apparemment, il faut aussi avoir de solides notions
de C...
Je pense qu'il serait utile, au lieu de modifier la fonction str du module python, d'ajouter une fonction "strnum", ou quelque autre nom que ce soit.
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour accéder à la librairie acl ?
Ben, heu: - parce que l'extension existe - parce que je ne connais pas ctypes (je suis relativement nouveau en python, j'ai surtout fait du bash et du php avant ces deux derniers mois).
Je vais voir de quoi il retourne...
- parce que j'ai lu le tutoriel de ctypes et que je n'y ai pas compris grand-chose :). Apparemment, il faut aussi avoir de solides notions de C...
-- Thomas Harding
hg
Thomas Harding wrote:
Le 08-07-2007, Thomas Harding a écrit :
Je pense qu'il serait utile, au lieu de modifier la fonction str du module python, d'ajouter une fonction "strnum", ou quelque autre nom que ce soit.
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour accéder à la librairie acl ?
Ben, heu: - parce que l'extension existe - parce que je ne connais pas ctypes (je suis relativement nouveau en python, j'ai surtout fait du bash et du php avant ces deux derniers mois).
Je vais voir de quoi il retourne...
- parce que j'ai lu le tutoriel de ctypes et que je n'y ai pas compris grand-chose :). Apparemment, il faut aussi avoir de solides notions de C...
-- Thomas Harding
Non, pas besoin d'être un champion en C.
Donne-moi une fonction à laquelle tu as besoin d'accéder, et je tente de de donner le code python qu'il faut pour te donner une idée.
hg
Thomas Harding wrote:
Le 08-07-2007, Thomas Harding <thomas.harding@laposte.net> a écrit :
Je pense qu'il serait utile, au lieu de modifier la fonction str du
module python, d'ajouter une fonction "strnum", ou quelque autre nom
que ce soit.
Pourquoi passer par une extension et ne pas simplement utiliser ctypes
pour accéder à la librairie acl ?
Ben, heu:
- parce que l'extension existe
- parce que je ne connais pas ctypes (je suis relativement nouveau en
python, j'ai surtout fait du bash et du php avant ces deux derniers
mois).
Je vais voir de quoi il retourne...
- parce que j'ai lu le tutoriel de ctypes et que je n'y ai pas compris
grand-chose :). Apparemment, il faut aussi avoir de solides notions
de C...
--
Thomas Harding
Non, pas besoin d'être un champion en C.
Donne-moi une fonction à laquelle tu as besoin d'accéder, et je tente de de
donner le code python qu'il faut pour te donner une idée.
Je pense qu'il serait utile, au lieu de modifier la fonction str du module python, d'ajouter une fonction "strnum", ou quelque autre nom que ce soit.
Pourquoi passer par une extension et ne pas simplement utiliser ctypes pour accéder à la librairie acl ?
Ben, heu: - parce que l'extension existe - parce que je ne connais pas ctypes (je suis relativement nouveau en python, j'ai surtout fait du bash et du php avant ces deux derniers mois).
Je vais voir de quoi il retourne...
- parce que j'ai lu le tutoriel de ctypes et que je n'y ai pas compris grand-chose :). Apparemment, il faut aussi avoir de solides notions de C...
-- Thomas Harding
Non, pas besoin d'être un champion en C.
Donne-moi une fonction à laquelle tu as besoin d'accéder, et je tente de de donner le code python qu'il faut pour te donner une idée.
PS: peux-tu me donner le/les définition(s) de __acl_ext ?
Thomas Harding
Le 08-07-2007, hg a écrit :
Non, pas besoin d'être un champion en C.
Donne-moi une fonction à laquelle tu as besoin d'accéder, et je tente de de donner le code python qu'il faut pour te donner une idée.
J'ai besoin d'accéder à acl_to_any_text avec le drapeau TEXT_NUMERIC_IDS. Seulement, je doute que ce soit suffisant... ces als sont ceux de fichiers du système, pas une liste quelconque.
extraits de libacl.h:
/* File: libacl.h
(C) 1999, 2000 Andreas Gruenbacher, */
#ifndef __ACL_LIBACL_H #define __ACL_LIBACL_H
#include <sys/acl.h>
[...]
/* Flags for acl_to_any_text() */
[...]
/* User and group IDs instead of names. */ #define TEXT_NUMERIC_IDS 0x08
Donne-moi une fonction à laquelle tu as besoin d'accéder, et je tente de de
donner le code python qu'il faut pour te donner une idée.
J'ai besoin d'accéder à acl_to_any_text avec le drapeau
TEXT_NUMERIC_IDS. Seulement, je doute que ce soit suffisant...
ces als sont ceux de fichiers du système, pas une liste quelconque.
extraits de libacl.h:
/*
File: libacl.h
(C) 1999, 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
*/
#ifndef __ACL_LIBACL_H
#define __ACL_LIBACL_H
#include <sys/acl.h>
[...]
/* Flags for acl_to_any_text() */
[...]
/* User and group IDs instead of names. */
#define TEXT_NUMERIC_IDS 0x08
Donne-moi une fonction à laquelle tu as besoin d'accéder, et je tente de de donner le code python qu'il faut pour te donner une idée.
J'ai besoin d'accéder à acl_to_any_text avec le drapeau TEXT_NUMERIC_IDS. Seulement, je doute que ce soit suffisant... ces als sont ceux de fichiers du système, pas une liste quelconque.
extraits de libacl.h:
/* File: libacl.h
(C) 1999, 2000 Andreas Gruenbacher, */
#ifndef __ACL_LIBACL_H #define __ACL_LIBACL_H
#include <sys/acl.h>
[...]
/* Flags for acl_to_any_text() */
[...]
/* User and group IDs instead of names. */ #define TEXT_NUMERIC_IDS 0x08
PS: peux-tu me donner le/les définition(s) de __acl_ext ?
Je ne saisis pas très bien ta question, mais :
le code de pylibacl (posix1e) est là :
http://pylibacl.sourceforge.net/
le code des acl linux ici :
ftp://oss.sgi.com/projects/xfs/cmd_tars/acl_2.2.44-1.tar.gz fichier à extraire: acl-2.2.44/libacl/libacl.h
Mais bon, je persiste de penser que passer par l'extension est la meilleure solution, sachant que la fonction dont j'ai besoin ne nécessite qu'une modification mineure.
De plus, ça évite à tout le monde de réinventer la roue à chaque fois...
Pour mes besoins immédiats, j'utilise deux versions de posix1e, la deuxième, que j'ai envoyée au début du fil, permettant d'extraire les acl avec utilisateur/groupe sous forme numérique.
-- Thomas Harding
Le 09-07-2007, hg <hg@nospam.org> a écrit :
PS: peux-tu me donner le/les définition(s) de __acl_ext ?
Je ne saisis pas très bien ta question, mais :
le code de pylibacl (posix1e) est là :
http://pylibacl.sourceforge.net/
le code des acl linux ici :
ftp://oss.sgi.com/projects/xfs/cmd_tars/acl_2.2.44-1.tar.gz
fichier à extraire:
acl-2.2.44/libacl/libacl.h
Mais bon, je persiste de penser que passer par l'extension est la
meilleure solution, sachant que la fonction dont j'ai besoin
ne nécessite qu'une modification mineure.
De plus, ça évite à tout le monde de réinventer la roue à chaque fois...
Pour mes besoins immédiats, j'utilise deux versions de posix1e,
la deuxième, que j'ai envoyée au début du fil, permettant
d'extraire les acl avec utilisateur/groupe sous forme numérique.
PS: peux-tu me donner le/les définition(s) de __acl_ext ?
Je ne saisis pas très bien ta question, mais :
le code de pylibacl (posix1e) est là :
http://pylibacl.sourceforge.net/
le code des acl linux ici :
ftp://oss.sgi.com/projects/xfs/cmd_tars/acl_2.2.44-1.tar.gz fichier à extraire: acl-2.2.44/libacl/libacl.h
Mais bon, je persiste de penser que passer par l'extension est la meilleure solution, sachant que la fonction dont j'ai besoin ne nécessite qu'une modification mineure.
De plus, ça évite à tout le monde de réinventer la roue à chaque fois...
Pour mes besoins immédiats, j'utilise deux versions de posix1e, la deuxième, que j'ai envoyée au début du fil, permettant d'extraire les acl avec utilisateur/groupe sous forme numérique.
-- Thomas Harding
hg
Thomas Harding wrote:
Le 09-07-2007, hg a écrit :
PS: peux-tu me donner le/les définition(s) de __acl_ext ?
Je ne saisis pas très bien ta question, mais :
le code de pylibacl (posix1e) est là :
http://pylibacl.sourceforge.net/
le code des acl linux ici :
ftp://oss.sgi.com/projects/xfs/cmd_tars/acl_2.2.44-1.tar.gz fichier à extraire: acl-2.2.44/libacl/libacl.h
Mais bon, je persiste de penser que passer par l'extension est la meilleure solution, sachant que la fonction dont j'ai besoin ne nécessite qu'une modification mineure.
De plus, ça évite à tout le monde de réinventer la roue à chaque fois...
Pour mes besoins immédiats, j'utilise deux versions de posix1e, la deuxième, que j'ai envoyée au début du fil, permettant d'extraire les acl avec utilisateur/groupe sous forme numérique.
-- Thomas Harding
SI tu regarde /usr/include/sys/acl.h, le type "__acl_ext" est défini comme suit:
struct __act_ext;
J'en conclu que le type de retour change d'un appel à l'autre.
Ou pour re-phraser, quand tu récupère des retours de fonction dans tes "structures" python, comment ces dernières sont-elles déclarées chez toi ?
hg
Thomas Harding wrote:
Le 09-07-2007, hg <hg@nospam.org> a écrit :
PS: peux-tu me donner le/les définition(s) de __acl_ext ?
Je ne saisis pas très bien ta question, mais :
le code de pylibacl (posix1e) est là :
http://pylibacl.sourceforge.net/
le code des acl linux ici :
ftp://oss.sgi.com/projects/xfs/cmd_tars/acl_2.2.44-1.tar.gz
fichier à extraire:
acl-2.2.44/libacl/libacl.h
Mais bon, je persiste de penser que passer par l'extension est la
meilleure solution, sachant que la fonction dont j'ai besoin
ne nécessite qu'une modification mineure.
De plus, ça évite à tout le monde de réinventer la roue à chaque fois...
Pour mes besoins immédiats, j'utilise deux versions de posix1e,
la deuxième, que j'ai envoyée au début du fil, permettant
d'extraire les acl avec utilisateur/groupe sous forme numérique.
--
Thomas Harding
SI tu regarde /usr/include/sys/acl.h, le type "__acl_ext" est défini comme
suit:
struct __act_ext;
J'en conclu que le type de retour change d'un appel à l'autre.
Ou pour re-phraser, quand tu récupère des retours de fonction dans
tes "structures" python, comment ces dernières sont-elles déclarées chez
toi ?
PS: peux-tu me donner le/les définition(s) de __acl_ext ?
Je ne saisis pas très bien ta question, mais :
le code de pylibacl (posix1e) est là :
http://pylibacl.sourceforge.net/
le code des acl linux ici :
ftp://oss.sgi.com/projects/xfs/cmd_tars/acl_2.2.44-1.tar.gz fichier à extraire: acl-2.2.44/libacl/libacl.h
Mais bon, je persiste de penser que passer par l'extension est la meilleure solution, sachant que la fonction dont j'ai besoin ne nécessite qu'une modification mineure.
De plus, ça évite à tout le monde de réinventer la roue à chaque fois...
Pour mes besoins immédiats, j'utilise deux versions de posix1e, la deuxième, que j'ai envoyée au début du fil, permettant d'extraire les acl avec utilisateur/groupe sous forme numérique.
-- Thomas Harding
SI tu regarde /usr/include/sys/acl.h, le type "__acl_ext" est défini comme suit:
struct __act_ext;
J'en conclu que le type de retour change d'un appel à l'autre.
Ou pour re-phraser, quand tu récupère des retours de fonction dans tes "structures" python, comment ces dernières sont-elles déclarées chez toi ?
hg
hg
Thomas Harding wrote:
Mais bon, je persiste de penser que passer par l'extension est la meilleure solution, sachant que la fonction dont j'ai besoin ne nécessite qu'une modification mineure.
Ben pas sûr ... les extensions de ce type sont difficiles à maintenir (je trouve) ... même swig finira par disparaître je crois ... mais bon ce n'est que mon humble avis.
hg
Thomas Harding wrote:
Mais bon, je persiste de penser que passer par l'extension est la
meilleure solution, sachant que la fonction dont j'ai besoin
ne nécessite qu'une modification mineure.
Ben pas sûr ... les extensions de ce type sont difficiles à maintenir (je
trouve) ... même swig finira par disparaître je crois ... mais bon ce n'est
que mon humble avis.
Mais bon, je persiste de penser que passer par l'extension est la meilleure solution, sachant que la fonction dont j'ai besoin ne nécessite qu'une modification mineure.
Ben pas sûr ... les extensions de ce type sont difficiles à maintenir (je trouve) ... même swig finira par disparaître je crois ... mais bon ce n'est que mon humble avis.