From efa7ac2eef94614ed6e8481b57b00cf25239581b Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 4 Apr 2021 03:31:26 +0200 Subject: misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- .gitignore | 9 +++ Makefile | 34 ++++++++++ TODO | 12 +++- add-contact.c | 46 ++++++++++++++ common.h | 5 ++ config.mk | 2 +- find-contact-by-number.c | 104 ++++++++++++++++++++++++++++++ get-contact-birthday.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++ get-contact-file.c | 3 +- get-contact-numbers.c | 91 +++++++++++++++++++++++++++ print-contact.c | 55 ++++++++++++++++ remove-contact.c | 32 ++++++++++ set-contact-numbers.c | 140 +++++++++++++++++++++++++++++++++++++++++ 13 files changed, 688 insertions(+), 5 deletions(-) create mode 100644 add-contact.c create mode 100644 find-contact-by-number.c create mode 100644 get-contact-birthday.c create mode 100644 get-contact-numbers.c create mode 100644 print-contact.c create mode 100644 remove-contact.c create mode 100644 set-contact-numbers.c diff --git a/.gitignore b/.gitignore index 3ce8ba4..2867b2c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,13 +9,16 @@ *.bo /contacts /contacts.c +/add-contact /find-contact-by-chat /find-contact-by-email /find-contact-by-name +/find-contact-by-number /find-contact-by-organisation /find-contact-by-pgpkey /find-contact-by-photo /find-contact-by-site +/get-contact-birthday /get-contact-chats /get-contact-emails /get-contact-file @@ -23,17 +26,22 @@ /get-contact-groups /get-contact-name /get-contact-notes +/get-contact-numbers /get-contact-organisations /get-contact-pgpkeys /get-contact-photos /get-contact-sites /is-contact-ice +/list-birthdays /list-chat-contacts /list-contact-groups /list-contact-organisations /list-contacts /list-group-contacts /list-organisation-contacts +/print-contact +/remove-contact +/set-contact-birthday /set-contact-chats /set-contact-emails /set-contact-gender @@ -41,6 +49,7 @@ /set-contact-ice /set-contact-name /set-contact-notes +/set-contact-numbers /set-contact-organisations /set-contact-pgpkeys /set-contact-photos diff --git a/Makefile b/Makefile index c821140..5ea2d5b 100644 --- a/Makefile +++ b/Makefile @@ -5,13 +5,16 @@ include $(CONFIGFILE) BIN =\ + add-contact\ find-contact-by-chat\ find-contact-by-email\ find-contact-by-name\ + find-contact-by-number\ find-contact-by-organisation\ find-contact-by-pgpkey\ find-contact-by-photo\ find-contact-by-site\ + get-contact-birthday\ get-contact-chats\ get-contact-emails\ get-contact-file\ @@ -19,6 +22,7 @@ BIN =\ get-contact-groups\ get-contact-name\ get-contact-notes\ + get-contact-numbers\ get-contact-organisations\ get-contact-pgpkeys\ get-contact-photos\ @@ -30,6 +34,8 @@ BIN =\ list-contacts\ list-group-contacts\ list-organisation-contacts\ + print-contact\ + remove-contact\ set-contact-chats\ set-contact-emails\ set-contact-gender\ @@ -37,6 +43,7 @@ BIN =\ set-contact-ice\ set-contact-name\ set-contact-notes\ + set-contact-numbers\ set-contact-organisations\ set-contact-pgpkeys\ set-contact-photos\ @@ -68,6 +75,9 @@ contacts.c: contacts.c.in Makefile printf '\n\n' >> $@ cat contacts.c.in >> $@ +add-contact: add-contact.o + $(CC) -o $@ $@.o $(LDFLAGS) + find-contact-by-chat: find-contact-by-chat.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -77,6 +87,9 @@ find-contact-by-email: find-contact-by-email.o find-contact-by-name: find-contact-by-name.o $(CC) -o $@ $@.o $(LDFLAGS) +find-contact-by-number: find-contact-by-number.o + $(CC) -o $@ $@.o $(LDFLAGS) + find-contact-by-organisation: find-contact-by-organisation.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -89,6 +102,9 @@ find-contact-by-photo: find-contact-by-photo.o find-contact-by-site: find-contact-by-site.o $(CC) -o $@ $@.o $(LDFLAGS) +get-contact-birthday: get-contact-birthday.o + $(CC) -o $@ $@.o $(LDFLAGS) + get-contact-chats: get-contact-chats.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -110,6 +126,9 @@ get-contact-name: get-contact-name.o get-contact-notes: get-contact-notes.o $(CC) -o $@ $@.o $(LDFLAGS) +get-contact-numbers: get-contact-numbers.o + $(CC) -o $@ $@.o $(LDFLAGS) + get-contact-organisations: get-contact-organisations.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -125,6 +144,9 @@ get-contact-sites: get-contact-sites.o is-contact-ice: is-contact-ice.o $(CC) -o $@ $@.o $(LDFLAGS) +list-birthdays: list-birthdays.o + $(CC) -o $@ $@.o $(LDFLAGS) + list-chat-contacts: list-chat-contacts.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -143,6 +165,15 @@ list-group-contacts: list-group-contacts.o list-organisation-contacts: list-organisation-contacts.o $(CC) -o $@ $@.o $(LDFLAGS) +print-contact: print-contact.o + $(CC) -o $@ $@.o $(LDFLAGS) + +remove-contact: remove-contact.o + $(CC) -o $@ $@.o $(LDFLAGS) + +set-contact-birthday: set-contact-birthday.o + $(CC) -o $@ $@.o $(LDFLAGS) + set-contact-chats: set-contact-chats.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -164,6 +195,9 @@ set-contact-name: set-contact-name.o set-contact-notes: set-contact-notes.o $(CC) -o $@ $@.o $(LDFLAGS) +set-contact-numbers: set-contact-numbers.o + $(CC) -o $@ $@.o $(LDFLAGS) + set-contact-organisations: set-contact-organisations.o $(CC) -o $@ $@.o $(LDFLAGS) diff --git a/TODO b/TODO index 5ad9943..f0c6588 100644 --- a/TODO +++ b/TODO @@ -1,29 +1,37 @@ +Add tools for checking context for contact info Add tools for .blocks -Add tools for .numbers Add tools for .addresses -Add tools for .birthday + +list-birthdays +set-contact-birthday Test find-contact-by-chat Test find-contact-by-email Test find-contact-by-name +Test find-contact-by-number Test find-contact-by-organisation Test find-contact-by-pgpkey Test find-contact-by-photo Test find-contact-by-site +Test get-contact-birthday Test get-contact-chats Test get-contact-emails Test get-contact-name +Test get-contact-numbers Test get-contact-organisations Test get-contact-pgpkeys Test get-contact-photos Test get-contact-sites +Test list-birthdays Test list-chat-contacts Test list-contact-organisations Test list-organisation-contacts +Test set-contact-birthday Test set-contact-chats Test set-contact-emails Test set-contact-groups Test set-contact-name +Test set-contact-numbers Test set-contact-organisations Test set-contact-pgpkeys Test set-contact-photos diff --git a/add-contact.c b/add-contact.c new file mode 100644 index 0000000..5a1b68c --- /dev/null +++ b/add-contact.c @@ -0,0 +1,46 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[contact-id]"); + + +int +main(int argc, char *argv[]) +{ + struct passwd *user; + struct libcontacts_contact contact; + char *path; + int fd; + + NOFLAGS(argc > 1); + + if (argc && (!*argv[0] || strchr(argv[0], '/'))) + usage(); + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + if (argc) { + path = libcontacts_get_path(argv[0], user); + if (!path) + eprintf("libcontacts_get_path %s:", argv[0]); + fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666); + if (fd < 0) + eprintf("open %s O_WRONLY|O_CREAT|O_EXCL 0666:", path); + if (close(fd)) + eprintf("close %s:", path); + free(path); + } else { + memset(&contact, 0, sizeof(contact)); + if (libcontacts_save_contact(&contact, user)) + eprintf("libcontacts_save_contact:"); + printf("%s\n", contact.id); + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + free(contact.id); + } + + return 0; +} diff --git a/common.h b/common.h index f4e1dad..ca6db51 100644 --- a/common.h +++ b/common.h @@ -4,6 +4,11 @@ #include +#ifndef BUFSIZ +# define BUFSIZ 4096 +#endif + + #ifdef MULTICALL_BINARY # undef NUSAGE # define NUSAGE(STATUS, SYNOPSIS)\ diff --git a/config.mk b/config.mk index 2c119c1..7145091 100644 --- a/config.mk +++ b/config.mk @@ -5,4 +5,4 @@ CC = cc CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -I../libcontacts CFLAGS = -std=c99 -Wall -O2 -LDFLAGS = -s -L../libcontacts -lcontacts -lsimple +LDFLAGS = -L../libcontacts -lcontacts -lsimple diff --git a/find-contact-by-number.c b/find-contact-by-number.c new file mode 100644 index 0000000..e426c57 --- /dev/null +++ b/find-contact-by-number.c @@ -0,0 +1,104 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c context] [-C local-country-calling-code] [-D address-book-country-calling-code] [-F | -f] [-M | -m] [-t] (-L | number)"); + + +int +main(int argc, char *argv[]) +{ + int list = 0, require_mobile = -1, require_fax = -1, display_type = 0; + struct passwd *user; + struct libcontacts_contact **contacts; + struct libcontacts_number **numbers, *number; + char *context = NULL, *cc_contacts = NULL, *cc_location = NULL; + size_t i; + + ARGBEGIN { + case 'c': + if (context) + usage(); + context = ARG(); + break; + case 'C': + if (cc_location) + usage(); + cc_location = ARG(); + break; + case 'D': + if (cc_contacts) + usage(); + cc_contacts = ARG(); + break; + case 'F': + if (require_fax >= 0) + usage(); + require_fax = 0; + break; + case 'f': + if (require_fax >= 0) + usage(); + require_fax = 1; + break; + case 'M': + if (require_mobile >= 0) + usage(); + require_mobile = 0; + break; + case 'm': + if (require_mobile >= 0) + usage(); + require_mobile = 1; + break; + case 'L': + list = 1; + break; + case 't': + display_type = 1; + break; + default: + usage(); + } ARGEND; + + if (argc != 1 - list) + usage(); + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + if (libcontacts_load_contacts(&contacts, user)) + eprintf("libcontacts_load_contacts:"); + for (i = 0; contacts[i]; i++) { + if ((numbers = contacts[i]->numbers)) { + for (; (number = *numbers); numbers++) { + if (!number->number) + continue; + if (require_mobile >= 0 && number->is_mobile != require_mobile) + continue; + if (require_fax >= 0 && number->is_facsimile != require_fax) + continue; + if (context && strcmpnul(number->context, context)) + continue; + if (list) { + if (display_type) + printf("%c%c ", "-m"[number->is_mobile], "-f"[number->is_facsimile]); + printf("%s (%s)\n", contacts[i]->id, number->number); + } else if (libcontacts_same_number(number->number, cc_contacts, argv[0], cc_location)) { + if (display_type) + printf("%c%c ", "-m"[number->is_mobile], "-f"[number->is_facsimile]); + printf("%s\n", contacts[i]->id); + } + } + } + libcontacts_contact_destroy(contacts[i]); + free(contacts[i]); + } + free(contacts); + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + + return 0; +} diff --git a/get-contact-birthday.c b/get-contact-birthday.c new file mode 100644 index 0000000..29be768 --- /dev/null +++ b/get-contact-birthday.c @@ -0,0 +1,160 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-n] contact-id ..."); + + +static int +get_age(struct libcontacts_birthday *bday, const struct tm *now) +{ + int age = now->tm_year + 1900 - (int)bday->year; + if (now->tm_mon + 1 < bday->month) + age -= 1; + else if (now->tm_mon + 1 == bday->month) + age -= (now->tm_mday < bday->day); + return age; +} + +static void +print_birthdate(struct libcontacts_birthday *bday, const struct tm *now) +{ + int age; + if (bday->year) + printf("%04u-", bday->year); + else + printf("??""??""-"); + if (bday->month) { + printf("(%02u)%.3s-", (unsigned)bday->month, + &"JanFebMarAprMayJunJulAugSepOctNovDec"[3 * ((bday->month - 1) % 12)]); + } else { + printf("(??"")??""?-"); + } + if (bday->day) + printf("%02u", (unsigned)bday->day); + else + printf("??"); + if ((bday->month - 1) % 12 == 1 && bday->day == 29) { + bday->day -= bday->before_on_common; + printf(" (%s on common years)", bday->before_on_common ? "(02)Feb-28" : "(03)Mar-01"); + } + if (bday->year && bday->month && bday->day) { + age = get_age(bday, now); + printf(", %i %s old today", age, age == 1 ? "year" : "years"); + } + printf("\n"); +} + +static void +print_birthday(struct libcontacts_birthday *bday, const struct tm *now) +{ + static const int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int next_year = 0, leap_year = 0, year, age, days = 0, y, m, d; + struct tm when; + if (now->tm_mon + 1 > bday->month) + next_year = 1; + else if (now->tm_mon + 1 == bday->month) + next_year = (now->tm_mday > bday->day); + if (bday->year) { + printf("%04i-", now->tm_year + next_year + 1900); + } else { + printf("??""??""-"); + } + year = now->tm_year + next_year + 1900; + if (year % 4 == 0 && (year % 100 || year % 400 == 0)) + leap_year = 1; + if (((bday->month - 1) % 12 == 1 && bday->day == 29) && leap_year) { + if (bday->before_on_common) { + bday->day -= 1; + } else { + bday->day = 1; + bday->month += 1; + } + } + printf("(%02u)%.3s-%02u (", (unsigned)bday->month % 12, + &"JanFebMarAprMayJunJulAugSepOctNovDec"[3 * ((bday->month - 1) % 12)], (unsigned)bday->day); + when.tm_year = now->tm_year + next_year; + when.tm_mon = (bday->month - 1) % 12; + when.tm_mday = bday->day; + if (bday->year) { + age = get_age(bday, &when); + printf("%i %s ", age, age == 1 ? "year" : "years"); + } + if (when.tm_mon == now->tm_mon && when.tm_mday == now->tm_mday) { + printf("today)\n"); + } else { + y = now->tm_year; + m = now->tm_mon; + d = now->tm_mday; + while (m != when.tm_mon || d > when.tm_mday) { + days += days_in_month[m] - (d - 1); + days += (m == 1 && y % 4 == 0 && (y % 100 || y % 400 == 0)); + d = 1; + if (++m == 12) { + y += 1; + m = 0; + } + } + days += when.tm_mday - d; + printf("in %i %s)\n", days, days == 1 ? "day" : "days"); + } + +} + +int +main(int argc, char *argv[]) +{ + int next = 0; + struct passwd *user; + struct libcontacts_contact contact; + struct tm *now; + time_t tim; + int ret = 0; + size_t i; + + ARGBEGIN { + case 'n': + next = 1; + break; + default: + usage(); + } ARGEND; + + if (!argc) + usage(); + + for (i = 0; argv[i]; i++) + if (!*argv[i] || strchr(argv[i], '/')) + usage(); + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + tim = time(NULL); + now = localtime(&tim); + if (!now) + eprintf("localtime:"); + + for (; *argv; argv++) { + if (libcontacts_load_contact(*argv, &contact, user)) { + weprintf("libcontacts_load_contact %s: %s\n", *argv, errno ? strerror(errno) : "contact file is malformatted"); + ret = 1; + } else { + if (contact.birthday) { + if (next) { + print_birthday(contact.birthday, now); + } else if (contact.birthday->month && contact.birthday->year) { + if (argc > 1) + printf("%s: ", *argv); + print_birthdate(contact.birthday, now); + } + } + libcontacts_contact_destroy(&contact); + } + } + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + return ret; +} diff --git a/get-contact-file.c b/get-contact-file.c index e244941..535d2f1 100644 --- a/get-contact-file.c +++ b/get-contact-file.c @@ -1,8 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" -/* Useful for deleting or backing up contacts */ - USAGE("contact-id"); @@ -30,5 +28,6 @@ main(int argc, char *argv[]) if (fflush(stdout) || ferror(stdout) || fclose(stdout)) eprintf("printf:"); + free(path); return 0; } diff --git a/get-contact-numbers.c b/get-contact-numbers.c new file mode 100644 index 0000000..0d9c02b --- /dev/null +++ b/get-contact-numbers.c @@ -0,0 +1,91 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c context] [-F | -f] [-M | -m] contact-id ..."); + + +int +main(int argc, char *argv[]) +{ + int require_mobile = -1, require_fax = -1; + struct passwd *user; + struct libcontacts_contact contact; + struct libcontacts_number **numbers, *number; + const char *lookup_ctx = NULL; + int ret = 0; + size_t i; + + ARGBEGIN { + case 'c': + if (lookup_ctx) + usage(); + lookup_ctx = ARG(); + break; + case 'F': + if (require_fax >= 0) + usage(); + require_fax = 0; + break; + case 'f': + if (require_fax >= 0) + usage(); + require_fax = 1; + break; + case 'M': + if (require_mobile >= 0) + usage(); + require_mobile = 0; + break; + case 'm': + if (require_mobile >= 0) + usage(); + require_mobile = 1; + break; + default: + usage(); + } ARGEND; + + if (!argc) + usage(); + + for (i = 0; argv[i]; i++) + if (!*argv[i] || strchr(argv[i], '/')) + usage(); + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + for (; *argv; argv++) { + if (libcontacts_load_contact(*argv, &contact, user)) { + weprintf("libcontacts_load_contact %s: %s\n", *argv, errno ? strerror(errno) : "contact file is malformatted"); + ret = 1; + continue; + } + if ((numbers = contact.numbers)) { + for (; (number = *numbers); numbers++) { + if (!number->number) + continue; + if (require_mobile >= 0 && number->is_mobile != require_mobile) + continue; + if (require_fax >= 0 && number->is_facsimile != require_fax) + continue; + if (lookup_ctx && strcmpnul(number->context, lookup_ctx)) + continue; + if (argc > 1) + printf("%s: ", *argv); + printf("%c%c", "-m"[number->is_mobile], "-f"[number->is_facsimile]); + if (!lookup_ctx) + printf(" %s (%s)\n", number->number, number->context); + else + printf(" %s\n", number->number); + } + } + libcontacts_contact_destroy(&contact); + } + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + return ret; +} diff --git a/print-contact.c b/print-contact.c new file mode 100644 index 0000000..7a9b92e --- /dev/null +++ b/print-contact.c @@ -0,0 +1,55 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("contact-id"); + + +int +main(int argc, char *argv[]) +{ + char buf[BUFSIZ]; + struct passwd *user; + char *path; + ssize_t r; + size_t n, p; + int fd; + + NOFLAGS(argc != 1); + + if (!*argv[0] || strchr(argv[0], '/')) + usage(); + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + path = libcontacts_get_path(argv[0], user); + if (!path) + eprintf("libcontacts_get_path %s:", argv[0]); + + fd = open(path, O_RDONLY); + if (fd < 0) + eprintf("open %s O_RDONLY:", path); + + for (;;) { + r = read(fd, buf, sizeof(buf)); + if (r <= 0) { + if (!r) + break; + eprintf("read %s:", path); + } + n = (size_t)r; + for (p = 0; p < n; p += (size_t)r) { + r = write(STDOUT_FILENO, &buf[p], n - p); + if (r <= 0) + eprintf("write :"); + } + } + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + close(fd); + free(path); + return 0; +} diff --git a/remove-contact.c b/remove-contact.c new file mode 100644 index 0000000..467abc2 --- /dev/null +++ b/remove-contact.c @@ -0,0 +1,32 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("contact-id"); + + +int +main(int argc, char *argv[]) +{ + struct passwd *user; + char *path; + + NOFLAGS(argc != 1); + + if (!*argv[0] || strchr(argv[0], '/')) + usage(); + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + path = libcontacts_get_path(argv[0], user); + if (!path) + eprintf("libcontacts_get_path %s:", argv[0]); + + if (unlink(path)) + eprintf("unlink %s:", path); + + free(path); + return 0; +} diff --git a/set-contact-numbers.c b/set-contact-numbers.c new file mode 100644 index 0000000..c03e175 --- /dev/null +++ b/set-contact-numbers.c @@ -0,0 +1,140 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c | -n] [-F | -f] [-M | -m] contact-id context number | -u contact-id context [number] | -U contact-id [context] number"); + + +int +main(int argc, char *argv[]) +{ + int set_facsimile = -1, set_mobile = -1; + int update_number = 0, update_context = 0; + int remove_by_context = 0, remove_by_number = 0; + struct passwd *user; + struct libcontacts_contact contact; + struct libcontacts_number **r, **w; + size_t i; + + ARGBEGIN { + case 'c': + update_context = 1; + break; + case 'n': + update_number = 1; + break; + case 'F': + if (set_facsimile >= 0) + return 0; + set_facsimile = 0; + break; + case 'f': + if (set_facsimile >= 0) + return 0; + set_facsimile = 1; + break; + case 'M': + if (set_mobile >= 0) + return 0; + set_mobile = 0; + break; + case 'm': + if (set_mobile >= 0) + return 0; + set_mobile = 1; + break; + case 'u': + remove_by_context = 1; + break; + case 'U': + remove_by_number = 1; + break; + default: + usage(); + } ARGEND; + + if (update_number + update_context + remove_by_context + remove_by_number > 0) + usage(); + if (argc < 3 - remove_by_context - remove_by_number || argc > 3) + usage(); + if ((set_facsimile >= 0 || set_mobile >= 0) && remove_by_context + remove_by_number) + usage(); + + if (!*argv[0] || strchr(argv[0], '/')) + usage(); + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + if (libcontacts_load_contact(argv[0], &contact, user)) + eprintf("libcontacts_load_contact %s: %s\n", argv[0], errno ? strerror(errno) : "contact file is malformatted"); + + i = 0; + if (contact.numbers) { + if (update_number) { + for (; contact.numbers[i]; i++) { + if (!strcmpnul(contact.numbers[i]->context, argv[1])) { + free(contact.numbers[i]->number); + contact.numbers[i]->number = estrdup(argv[2]); + goto save; + } + } + } else if (update_context) { + for (; contact.numbers[i]; i++) { + if (!strcmpnul(contact.numbers[i]->number, argv[2])) { + free(contact.numbers[i]->context); + contact.numbers[i]->context = estrdup(argv[1]); + goto save; + } + } + } else if (!remove_by_context && !remove_by_number) { + for (; contact.numbers[i]; i++) { + if (!strcmpnul(contact.numbers[i]->context, argv[1])) + if (!strcmpnul(contact.numbers[i]->number, argv[2])) + goto save; + } + } else if (argc == 3) { + for (; contact.numbers[i]; i++) + if (!strcmpnul(contact.numbers[i]->context, argv[1])) + if (!strcmpnul(contact.numbers[i]->number, argv[2])) + break; + } else if (remove_by_context) { + for (; contact.numbers[i]; i++) + if (!strcmpnul(contact.numbers[i]->context, argv[1])) + break; + } else { + for (; contact.numbers[i]; i++) + if (!strcmpnul(contact.numbers[i]->number, argv[1])) + break; + } + } + if (remove_by_context || remove_by_number) { + if (contact.numbers && contact.numbers[i]) { + libcontacts_number_destroy(contact.numbers[i]); + free(contact.numbers[i]); + for (r = &1[w = &contact.numbers[i]]; *r;) + *w++ = *r++; + *w = NULL; + } + } else { + contact.numbers = erealloc(contact.numbers, (i + 2) * sizeof(*contact.numbers)); + contact.numbers[i + 1] = NULL; + contact.numbers[i] = ecalloc(1, sizeof(**contact.numbers)); + contact.numbers[i]->context = estrdup(argv[1]); + contact.numbers[i]->number = estrdup(argv[2]); + contact.numbers[i]->is_mobile = set_mobile > 0; + contact.numbers[i]->is_facsimile = set_facsimile > 0; + } + +save: + if (set_mobile >= 0) + contact.numbers[i]->is_mobile = set_mobile; + if (set_facsimile >= 0) + contact.numbers[i]->is_facsimile = set_facsimile; + if (libcontacts_save_contact(&contact, user)) + eprintf("libcontacts_save_contact %s:", argv[0]); + libcontacts_contact_destroy(&contact); + + return 0; +} -- cgit v1.2.3-70-g09d2