/* Copyright (C) 2003 MandrakeSoft SA Daouda Lo (daouda at mandrakesoft dot com) * This program is free software; you can redistribute it and/or * modify it under the same terms as Perl itself. */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include #include #include #include #include #include #include typedef struct lu_context USER__ADMIN; typedef struct lu_ent USER__ENT; typedef struct lu_error USER__ERR; static SV ** convert_value_array_list(register SV **sp, GValueArray *array) { GValue *value; int i; long l; STRLEN len; const char *s; for (i = 0; (array != NULL) && (i < array->n_values); i++) { value = g_value_array_get_nth(array, i); /* If the item is a G_TYPE_LONG, add it as a double. */ if (G_VALUE_HOLDS_LONG(value)) { l = g_value_get_long(value); XPUSHs(sv_2mortal(newSViv(l))); } else if (G_VALUE_HOLDS_STRING(value)) { s = g_value_get_string(value); XPUSHs(sv_2mortal(newSVpv(s, len))); } } return sp; } char * get_name(USER__ENT *ent, const char *attribute) { GValueArray *values; GValue *value; char *name; values = lu_ent_get(ent, attribute); value = gvalue_array_get_nth(values, 0); strcpy(name, g_value_get_string(value)); return name; } static int get_int(USER__ENT *ent, const char *attribute) { GValueArray *values; GValue *value; int i; values = lu_ent_get(ent, attribute); value = gvalue_array_get_nth(values, 0); i = g_value_get_long(value); return i ? i : -1; } MODULE = USER PACKAGE = USER::ADMIN PREFIX = Admin_ USER::ADMIN * Admin_new(CLASS) char *CLASS CODE: RETVAL = (USER__ADMIN *)safemalloc( sizeof( USER__ADMIN ) ); if( RETVAL == NULL ){ warn("unable to malloc USER__ADMIN"); XSRETURN_UNDEF; } OUTPUT: RETVAL void Admin_start(self) USER::ADMIN *self CODE: USER__ERR error; self = lu_start(NULL, 0, NULL, NULL, NULL, NULL, &error); void Admin_DESTROY(self) USER::ADMIN *self CODE: lu_end(self); lu_ctx_free(self) void Admin_lookup_user_name(self, name) USER::ADMIN *self char *name PREINIT: USER::ENT *ent; USER__ERR *err; PPCODE: ent = lu_ent_new(); if ( lu_user_lookup_name(self, name, ent, &err)) { XPUSHs(sv_2mortal(newSViv(ent))) } else { /* No such user. Clean up and bug out. */ lu_ent_free(ent); } AV * Admin_users_enumerate_full(self, pattern) USER::ADMIN *self char *pattern PREINIT: int c; USER__ERR *err; CODE: RETVAL = (AV*)sv_2mortal((SV*)newAV()); GPtrArray *accounts; results=lu_users_enumerate_full(self, pattern, &error); for (c = 0; (accounts != NULL) && (c < accounts->len); c++) { if( av_store( RETVAL, c, newSViv(g_ptr_array_index(accounts, c)) ) == NULL ){ warn("XS_UsersEnumerateFull: failed to store elems"); } } g_ptr_array_free(accounts, TRUE); OUTPUT: RETVAL AV * Admin_groups_enumerate_full(self, pattern) USER::ADMIN *self char *pattern PREINIT: int c; USER__ERR *err; CODE: RETVAL = (AV*)sv_2mortal((SV*)newAV()); GPtrArray *accounts; results=lu_groups_enumerate_full(self, pattern, &error); for (c = 0; (accounts != NULL) && (c < accounts->len); c++) { if( av_store( RETVAL, c, newSViv(g_ptr_array_index(accounts, c)) ) == NULL ){ warn("XS_UsersEnumerateFull: failed to store elems"); } } g_ptr_array_free(accounts, TRUE); OUTPUT: RETVAL MODULE = USER PACKAGE = USER::ENT Prefix = PREFIX_ USER::ENT * Ent_new (CLASS) char *CLASS CODE: RETVAL = (USER__ENT *)safemalloc( sizeof( USER__ENT ) ); if( RETVAL == NULL ){ warn("unable to malloc USER__ENT"); XSRETURN_UNDEF; } OUTPUT: RETVAL void Ent_begin(self) USER::ENT *self PPCODE: self = lu_ent_new() void Ent_DESTROY(self) USER::ENT *self CODE: lu_ent_free(self); safefree(self) HV * Ent_get_attributes(self) USER::ENT *self CODE: int i,j; RETVAL = (HV*)sv_2mortal((SV*)newHV()); switch (self->type) { case lu_invalid: break; case lu_user: hv_store(RETVAL, "type", 4, newSVpv("user"), 0); hv_store(RETVAL, "username", 8, newSVpv(get_name(ent, LU_USERNAME)), 0); hv_store(RETVAL, "uid", 3, newSViv(get_int(ent, LU_UIDNUMBER)), 0); hv_store(RETVAL, "gid", 3, newSViv(get_int(ent, LU_GIDNUMBER)), 0); hv_store(RETVAL, "gecos", 5, newSVpv(get_name(ent, LU_GECOS)), 0); hv_store(RETVAL, "home", 4, newSVpv(get_name(ent, LU_HOMEDIRECTORY)), 0); hv_store(RETVAL, "shell", 5, newSVpv(get_name(ent, LU_LOGINSHELL)), 0); hv_store(RETVAL, "shadowpass", 10, newSVpv(get_name(ent, LU_SHADOWPASSWORD)), 0); hv_store(RETVAL, "shadowlastchange", 16, newSViv(get_name(ent, LU_SHADOWLASTCHANGE)), 0); hv_store(RETVAL, "shadowmin", 9, newSViv(get_name(ent, LU_SHADOWMIN)), 0); hv_store(RETVAL, "shadowmax", 9, newSViv(get_name(ent, LU_SHADOWMAX)), 0); hv_store(RETVAL, "shadowwarning", 13, newSVpv(get_name(ent, LU_SHADOWWARNING)), 0); hv_store(RETVAL, "shadowinact", 11, newSViv(get_name(ent, LU_SHADOWINACTIVE)), 0); hv_store(RETVAL, "shadowexpire", 12, newSViv(get_name(ent, LU_SHADOWINACTIVE)), 0); hv_store(RETVAL, "shadowflag", 10, newSViv(get_name(ent, LU_SHADOWINACTIVE)), 0); case lu_group: hv_store(RETVAL, "type", 4, newSVpv("group"), 0); hv_store(RETVAL, "groupname", 8, newSVpv(get_name(ent, LU_GROUPNAME)), 0); hv_store(RETVAL, "gid", 3, newSViv(get_int(ent, LU_GIDNUMBER)), 0); break; default: break; } OUTPUT: RETVAL