aboutsummaryrefslogtreecommitdiffstats
path: root/libcontacts_list_contacts.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcontacts_list_contacts.c')
-rw-r--r--libcontacts_list_contacts.c61
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;
+}