diff options
Diffstat (limited to 'libcontacts_list_contacts.c')
-rw-r--r-- | libcontacts_list_contacts.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/libcontacts_list_contacts.c b/libcontacts_list_contacts.c new file mode 100644 index 0000000..e4794f0 --- /dev/null +++ b/libcontacts_list_contacts.c @@ -0,0 +1,61 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +int +libcontacts_list_contacts(char ***idsp, const struct passwd *user) +{ + char *dirnam; + DIR *dir; + struct dirent *f; + size_t i = 0; + void *new; + int saved_errno = errno; + + *idsp = NULL; + + dirnam = libcontacts_get_path("", user); + if (!dirnam) + return -1; + + dir = opendir(dirnam); + if (!dir) { + free(dirnam); + return -1; + } + + goto start; + while ((f = readdir(dir))) { + if (strchr(f->d_name, '.')) + continue; + if (!f->d_name[0] || strchr(f->d_name, '\0')[-1] == '~') + continue; + if (!((*idsp)[i++] = strdup(f->d_name))) + goto fail; + start: + new = realloc(*idsp, (i + 1) * sizeof(**idsp)); + if (!new) + goto fail; + *idsp = new; + } + (*idsp)[i] = NULL; + + if (errno) + goto fail; + closedir(dir); + free(dirnam); + errno = saved_errno; + return 0; + +fail: + saved_errno = errno; + closedir(dir); + free(dirnam); + if (*idsp) { + for (i = 0; (*idsp)[i]; i++) + free((*idsp)[i]); + free(*idsp); + } + errno = saved_errno; + return -1; +} |