diff options
author | Mattias Andrée <maandree@kth.se> | 2021-04-02 13:17:25 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2021-04-02 13:21:07 +0200 |
commit | 8b52cc7243c2e0e4ef17db5583999030b8636584 (patch) | |
tree | 29d4985285ecbbce2c7ec1cf61837ede3fccf526 /libcontacts_load_contact.c | |
download | libcontacts-8b52cc7243c2e0e4ef17db5583999030b8636584.tar.gz libcontacts-8b52cc7243c2e0e4ef17db5583999030b8636584.tar.bz2 libcontacts-8b52cc7243c2e0e4ef17db5583999030b8636584.tar.xz |
First commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'libcontacts_load_contact.c')
-rw-r--r-- | libcontacts_load_contact.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/libcontacts_load_contact.c b/libcontacts_load_contact.c new file mode 100644 index 0000000..2d6f933 --- /dev/null +++ b/libcontacts_load_contact.c @@ -0,0 +1,65 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +int +libcontacts_load_contact(const char *id, struct libcontacts_contact *contact, const struct passwd *user) +{ + int ret, fd, saved_errno; + char *data = NULL, *path; + size_t p = 0, n = 0; + ssize_t r; + void *new; + + if (!contact) { + errno = EINVAL; + return -1; + } + + path = libcontacts_get_path(id, user); + if (!path) + return -1; + fd = open(path, O_RDONLY); + free(path); + if (fd < 0) + return -1; + + for (;;) { + if (p == n) { + new = realloc(data, n + (8 << 10) + 1); + if (!new) + goto fail; + n += 8 << 10; + } + r = read(fd, &data[p], n - p); + if (r <= 0) { + if (r) + goto fail; + break; + } + p += (size_t)r; + } + data[p] = '\0'; + + if (memchr(data, 0, p)) { + errno = 0; + goto fail; + } + + close(fd); + ret = libcontacts_parse_contact(data, contact); + free(data); + if (!ret && !(contact->id = strdup(id))) { + libcontacts_contact_destroy(contact); + memset(contact, 0, sizeof(*contact)); + return -1; + } + return ret; + +fail: + saved_errno = errno; + free(data); + close(fd); + errno = saved_errno; + return -1; +} |