diff options
author | Mattias Andrée <maandree@kth.se> | 2021-04-12 00:07:26 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2021-04-12 00:07:26 +0200 |
commit | 1a21982ebc2747a694558c6e82cea54bd5dbead9 (patch) | |
tree | 42a145211772e876d85dfcc65655fa3130016313 | |
parent | Improve set-contact- utils (diff) | |
download | contacts-1a21982ebc2747a694558c6e82cea54bd5dbead9.tar.gz contacts-1a21982ebc2747a694558c6e82cea54bd5dbead9.tar.bz2 contacts-1a21982ebc2747a694558c6e82cea54bd5dbead9.tar.xz |
Deduplicate code and make some minor improvements
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | common.h | 160 | ||||
-rw-r--r-- | set-contact-birthday.c | 3 | ||||
-rw-r--r-- | set-contact-blocks.c | 28 | ||||
-rw-r--r-- | set-contact-chats.c | 137 | ||||
-rw-r--r-- | set-contact-emails.c | 118 | ||||
-rw-r--r-- | set-contact-gender.c | 3 | ||||
-rw-r--r-- | set-contact-groups.c | 11 | ||||
-rw-r--r-- | set-contact-numbers.c | 146 | ||||
-rw-r--r-- | set-contact-organisations.c | 118 | ||||
-rw-r--r-- | set-contact-pgpkeys.c | 118 | ||||
-rw-r--r-- | set-contact-photos.c | 32 | ||||
-rw-r--r-- | set-contact-sites.c | 118 |
13 files changed, 241 insertions, 758 deletions
@@ -11,14 +11,7 @@ Test list-chat-contacts Test list-contact-organisations Test list-organisation-contacts Test set-contact-blocks -Test set-contact-chats -Test set-contact-emails -Test set-contact-groups -Test set-contact-numbers -Test set-contact-organisations -Test set-contact-pgpkeys Test set-contact-photos -Test set-contact-sites Test unblock-contact Add ability to filter on unset values in entries Add ability to remove values in entries @@ -25,3 +25,163 @@ void print_birthday(struct libcontacts_birthday *bday, const struct tm *now); /* common-address.c */ int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, double *lon, double *lon_min, double *lon_max); + + + +#ifndef LIST_BOOL_PARAMS +# define LIST_BOOL_PARAMS(X) +#endif + +#define X_USAGE_UPPER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + "[-"UPPERS" old-"DISPLAY"] " + +#define X_USAGE_LOWER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + "[-"LOWERS" new-"DISPLAY"] " + +#define X_USAGE_BOOL(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + "[-"UPPERS" | -"LOWERS"] " + +#define X_PARAMS(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + char *VAR = NULL, *lookup_##VAR = NULL, *old_##VAR = NULL; + +#define X_BOOL_PARAMS(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + int set_##VAR = -1; + +#define X_ARGPARSE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + case UPPERC:\ + add = 0;\ + if (lookup_##VAR)\ + usage();\ + lookup_##VAR = ARG();\ + break;\ + case LOWERC:\ + edit = 1;\ + if (VAR)\ + usage();\ + VAR = ARG();\ + break; + +#define X_BOOL_ARGPARSE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + case UPPERC:\ + if (set_##VAR >= 0)\ + usage();\ + set_##VAR = 0;\ + break;\ + case LOWERC:\ + if (set_##VAR >= 0)\ + usage();\ + set_##VAR = 1;\ + break; + +#define X_LOWER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + LOWERS + +#define X_LOOKUP(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + if (lookup_##VAR && strcmpnul(contact.CATEGORY[i]->VAR, lookup_##VAR))\ + continue; + +#define X_BOOL_LOOKUP(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + if (remove && set_##VAR >= 0 && contact.CATEGORY[i]->is_##VAR != set_##VAR)\ + continue; + +#define X_CHANGE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + if (VAR) {\ + old_##VAR = contact.CATEGORY[i]->VAR;\ + contact.CATEGORY[i]->VAR = VAR;\ + } + +#define X_BOOL_SET(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + if (set_##VAR >= 0)\ + contact.CATEGORY[i]->is_##VAR = set_##VAR; + +#define X_ADD(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + contact.CATEGORY[i]->VAR = VAR; + +#define X_RESTORE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\ + contact.CATEGORY[i]->VAR = old_##VAR; + +#define IMPLEMENT_SET_ON_LIST(CAT)\ + USAGE(LIST_PARAMS(X_USAGE_UPPER)LIST_BOOL_PARAMS(X_USAGE_BOOL)"("LIST_PARAMS(X_USAGE_LOWER)"| -u) contact-id");\ + \ + int\ + main(int argc, char *argv[])\ + {\ + int add = 1, edit = 0, remove = 0;\ + LIST_PARAMS(X_PARAMS)\ + LIST_BOOL_PARAMS(X_BOOL_PARAMS)\ + struct passwd *user;\ + struct libcontacts_contact contact;\ + struct libcontacts_##CAT **r = NULL, **w;\ + size_t i;\ + \ + ARGBEGIN {\ + LIST_PARAMS(X_ARGPARSE)\ + LIST_BOOL_PARAMS(X_BOOL_ARGPARSE)\ + case 'u':\ + remove = 1;\ + break;\ + default:\ + usage();\ + } ARGEND;\ + \ + if (argc != 1 || !*argv[0] || strchr(argv[0], '/'))\ + usage();\ + \ + if (remove == edit) {\ + if (edit)\ + usage();\ + eprintf("at least one of -"LIST_PARAMS(X_LOWER)"u is required\n");\ + }\ + \ + if (add)\ + edit = 0;\ + \ + 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 ((edit || remove) && contact.CATEGORY) {\ + for (; contact.CATEGORY[i]; i++) {\ + LIST_PARAMS(X_LOOKUP)\ + LIST_BOOL_PARAMS(X_BOOL_LOOKUP)\ + break;\ + }\ + if (!contact.CATEGORY[i]) {\ + libcontacts_contact_destroy(&contact);\ + return 0;\ + } else if (!edit) {\ + r = &contact.CATEGORY[i];\ + libcontacts_##CAT##_destroy(*r);\ + free(*r);\ + for (w = r++; (*w++ = *r++););\ + } else {\ + LIST_PARAMS(X_CHANGE)\ + LIST_BOOL_PARAMS(X_BOOL_SET)\ + }\ + } else if (!edit && !remove) {\ + if (contact.CATEGORY)\ + for (; contact.CATEGORY[i]; i++);\ + contact.CATEGORY = erealloc(contact.CATEGORY, (i + 2) * sizeof(*contact.CATEGORY));\ + contact.CATEGORY[i + 1] = NULL;\ + contact.CATEGORY[i] = ecalloc(1, sizeof(**contact.CATEGORY));\ + LIST_PARAMS(X_ADD)\ + LIST_BOOL_PARAMS(X_BOOL_SET)\ + }\ + \ + if (libcontacts_save_contact(&contact, user))\ + eprintf("libcontacts_save_contact %s:", argv[0]);\ + \ + if (!r) {\ + LIST_PARAMS(X_RESTORE)\ + }\ + \ + libcontacts_contact_destroy(&contact);\ + return 0;\ + } diff --git a/set-contact-birthday.c b/set-contact-birthday.c index 74dadc7..c65e65d 100644 --- a/set-contact-birthday.c +++ b/set-contact-birthday.c @@ -106,7 +106,8 @@ main(int argc, char *argv[]) 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"); + weprintf("libcontacts_load_contact %s: %s\n", *argv, + errno ? strerror(errno) : "contact file is malformatted"); ret = 1; } else { if (remove) { diff --git a/set-contact-blocks.c b/set-contact-blocks.c index dc01919..9e1ada5 100644 --- a/set-contact-blocks.c +++ b/set-contact-blocks.c @@ -13,9 +13,9 @@ main(int argc, char *argv[]) enum libcontacts_block_type lookup_shadow_block = LIBCONTACTS_BLOCK_IGNORE; time_t soft_unblock = 0, hard_unblock = 0; time_t lookup_soft_unblock = 0, lookup_hard_unblock = 0; - char *srv = NULL, *type = NULL, *style = NULL, *ask = NULL, *ublk = NULL; - char *lookup_srv = NULL, *lookup_type = NULL, *lookup_style = NULL; - char *lookup_ask = NULL, *lookup_ublk = NULL, *old_srv = NULL, global[] = ".global"; + const char *srv = NULL, *type = NULL, *style = NULL, *ask = NULL, *ublk = NULL; + const char *lookup_srv = NULL, *lookup_type = NULL, *lookup_style = NULL; + const char *lookup_ask = NULL, *lookup_ublk = NULL; struct passwd *user; struct libcontacts_contact contact; char *p; @@ -106,9 +106,6 @@ main(int argc, char *argv[]) usage(); } ARGEND; - if (add) - edit = 0; - if (argc != 1 || !*argv[0] || strchr(argv[0], '/')) usage(); @@ -156,17 +153,22 @@ main(int argc, char *argv[]) eprintf("value of -y shall be either \"silent\", \"as-off\", \"as-busy\", or \"ignore\"\n"); } + if (add) + edit = 0; + 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"); + 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 (edit && contact.blocks) { - for (i = 0; contact.blocks[i]; i++) { + for (; contact.blocks[i]; i++) { if (lookup_srv && strcmpnul(contact.blocks[i]->service, lookup_srv)) continue; if (lookup_type && contact.blocks[i]->explicit != lookup_explicit) @@ -178,8 +180,8 @@ main(int argc, char *argv[]) if (lookup_ublk && contact.blocks[i]->hard_unblock != lookup_hard_unblock) continue; if (srv) { - old_srv = contact.blocks[i]->service; - contact.blocks[i]->service = srv; + free(contact.blocks[i]->service); + contact.blocks[i]->service = estrdup(srv); } if (type) contact.blocks[i]->explicit = explicit; @@ -196,7 +198,7 @@ main(int argc, char *argv[]) contact.blocks = erealloc(contact.blocks, (i + 2) * sizeof(*contact.blocks)); contact.blocks[i + 1] = NULL; contact.blocks[i] = ecalloc(1, sizeof(**contact.emails)); - contact.blocks[i]->service = srv ? srv : global; + contact.blocks[i]->service = estrdup(srv ? srv : ".global"); contact.blocks[i]->explicit = explicit; contact.blocks[i]->shadow_block = shadow_block; contact.blocks[i]->soft_unblock = soft_unblock; @@ -206,8 +208,6 @@ main(int argc, char *argv[]) if (libcontacts_save_contact(&contact, user)) eprintf("libcontacts_save_contact %s:", argv[0]); - contact.blocks[i]->service = old_srv; libcontacts_contact_destroy(&contact); - return 0; } diff --git a/set-contact-chats.c b/set-contact-chats.c index d2811d0..a4e0f8d 100644 --- a/set-contact-chats.c +++ b/set-contact-chats.c @@ -1,133 +1,10 @@ /* See LICENSE file for copyright and license details. */ -#include "common.h" - -USAGE("[-A old-address] [-C old-context] [-S old-service] ([-a new-adress] [-c new-context] [-s new-service] | -u) contact-id"); - - -int -main(int argc, char *argv[]) -{ - int add = 1, edit = 0, remove = 0; - char *address = NULL, *context = NULL, *service = NULL; - char *lookup_address = NULL, *lookup_context = NULL, *lookup_service = NULL; - char *old_address = NULL, *old_context = NULL, *old_service = NULL; - struct passwd *user; - struct libcontacts_contact contact; - struct libcontacts_chat **r, **w; - size_t i; - - ARGBEGIN { - case 'A': - add = 0; - if (lookup_address) - usage(); - lookup_address = ARG(); - break; - case 'a': - edit = 1; - if (address) - usage(); - address = ARG(); - break; - case 'C': - add = 0; - if (lookup_context) - usage(); - lookup_context = ARG(); - break; - case 'c': - edit = 1; - if (context) - usage(); - context = ARG(); - break; - case 'S': - add = 0; - if (lookup_service) - usage(); - lookup_service = ARG(); - break; - case 's': - edit = 1; - if (service) - usage(); - service = ARG(); - break; - case 'u': - remove = 1; - break; - default: - usage(); - } ARGEND; - - if (remove == edit) { - if (edit) - usage(); - eprintf("at least one of -acsu is required\n"); - } - - if (add) - edit = 0; +#define CATEGORY chats - if (argc != 1 || !*argv[0] || strchr(argv[0], '/')) - usage(); +#define LIST_PARAMS(X)\ + X('A', "A", 'a', "a", address, "address")\ + X('S', "S", 's', "s", service, "service")\ + X('C', "C", 'c', "c", context, "context") - 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 ((edit || remove) && contact.chats) { - for (r = contact.chats; *r; r++) { - if (lookup_context && strcmpnul((*r)->context, lookup_context)) - continue; - if (lookup_address && strcmpnul((*r)->context, lookup_address)) - continue; - break; - } - if (!edit) { - libcontacts_chat_destroy(*r); - free(*r); - for (w = r++; (*w++ = *r++);); - } else if (*r) { - if (context) { - old_context = contact.chats[i]->context; - contact.chats[i]->context = context; - } - if (service) { - old_service = contact.chats[i]->service; - contact.chats[i]->service = service; - } - if (address) { - old_address = contact.chats[i]->address; - contact.chats[i]->address = address; - } - } else { - libcontacts_contact_destroy(&contact); - return 0; - } - } else if (!edit && !remove) { - if (contact.chats) - for (i = 0; contact.chats[i]; i++); - contact.chats = erealloc(contact.chats, (i + 2) * sizeof(*contact.chats)); - contact.chats[i + 1] = NULL; - contact.chats[i] = ecalloc(1, sizeof(**contact.chats)); - contact.chats[i]->context = context; - contact.chats[i]->service = service; - contact.chats[i]->address = address; - } - - if (libcontacts_save_contact(&contact, user)) - eprintf("libcontacts_save_contact %s:", argv[0]); - - contact.chats[i]->context = old_context; - contact.chats[i]->service = old_service; - contact.chats[i]->address = old_address; - libcontacts_contact_destroy(&contact); - - return 0; -} +#include "common.h" +IMPLEMENT_SET_ON_LIST(chat) diff --git a/set-contact-emails.c b/set-contact-emails.c index d1cece5..31efe8c 100644 --- a/set-contact-emails.c +++ b/set-contact-emails.c @@ -1,115 +1,9 @@ /* See LICENSE file for copyright and license details. */ -#include "common.h" - -USAGE("[-A old-address] [-C old-context] ([-a new-adress] [-c new-context] | -u) contact-id"); - - -int -main(int argc, char *argv[]) -{ - int add = 1, edit = 0, remove = 0; - char *address = NULL, *context = NULL; - char *lookup_address = NULL, *lookup_context = NULL; - char *old_address = NULL, *old_context = NULL; - struct passwd *user; - struct libcontacts_contact contact; - struct libcontacts_email **r, **w; - size_t i; - - ARGBEGIN { - case 'A': - add = 0; - if (lookup_address) - usage(); - lookup_address = ARG(); - break; - case 'a': - edit = 1; - if (address) - usage(); - address = ARG(); - break; - case 'C': - add = 0; - if (lookup_context) - usage(); - lookup_context = ARG(); - break; - case 'c': - edit = 1; - if (context) - usage(); - context = ARG(); - break; - case 'u': - remove = 1; - break; - default: - usage(); - } ARGEND; - - if (remove == edit) { - if (edit) - usage(); - eprintf("at least one of -acu is required\n"); - } - - if (add) - edit = 0; +#define CATEGORY emails - if (argc != 1 || !*argv[0] || strchr(argv[0], '/')) - usage(); +#define LIST_PARAMS(X)\ + X('A', "A", 'a', "a", address, "address")\ + X('C', "C", 'c', "c", context, "context") - 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 ((edit || remove) && contact.emails) { - for (r = contact.emails; *r; r++) { - if (lookup_context && strcmpnul((*r)->context, lookup_context)) - continue; - if (lookup_address && strcmpnul((*r)->context, lookup_address)) - continue; - break; - } - if (!edit) { - libcontacts_email_destroy(*r); - free(*r); - for (w = r++; (*w++ = *r++);); - } else if (*r) { - if (context) { - old_context = contact.emails[i]->context; - contact.emails[i]->context = context; - } - if (address) { - old_address = contact.emails[i]->address; - contact.emails[i]->address = address; - } - } else { - libcontacts_contact_destroy(&contact); - return 0; - } - } else if (!edit && !remove) { - if (contact.emails) - for (i = 0; contact.emails[i]; i++); - contact.emails = erealloc(contact.emails, (i + 2) * sizeof(*contact.emails)); - contact.emails[i + 1] = NULL; - contact.emails[i] = ecalloc(1, sizeof(**contact.emails)); - contact.emails[i]->context = context; - contact.emails[i]->address = address; - } - - if (libcontacts_save_contact(&contact, user)) - eprintf("libcontacts_save_contact %s:", argv[0]); - - contact.emails[i]->context = old_context; - contact.emails[i]->address = old_address; - libcontacts_contact_destroy(&contact); - - return 0; -} +#include "common.h" +IMPLEMENT_SET_ON_LIST(email) diff --git a/set-contact-gender.c b/set-contact-gender.c index b0b0258..70b9150 100644 --- a/set-contact-gender.c +++ b/set-contact-gender.c @@ -55,7 +55,8 @@ main(int argc, char *argv[]) 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"); + weprintf("libcontacts_load_contact %s: %s\n", *argv, + errno ? strerror(errno) : "contact file is malformatted"); ret = 1; continue; } diff --git a/set-contact-groups.c b/set-contact-groups.c index 2b8e3c1..f0408c5 100644 --- a/set-contact-groups.c +++ b/set-contact-groups.c @@ -39,7 +39,8 @@ main(int argc, char *argv[]) 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"); + weprintf("libcontacts_load_contact %s: %s\n", *argv, + errno ? strerror(errno) : "contact file is malformatted"); ret = 1; continue; } @@ -48,17 +49,15 @@ main(int argc, char *argv[]) if (!strcmp(contact.groups[i], group)) break; r = &contact.groups[i]; + if (!remove && !*r) + goto add_group; if (remove && *r) { free(*r); - for (w = r++; *r;) - *w++ = *r++; - *w = NULL; + for (w = r++; (*w++ = *r++);); if (libcontacts_save_contact(&contact, user)) { weprintf("libcontacts_save_contact %s:", *argv); ret = 1; } - } else if (!remove && !*r) { - goto add_group; } } else if (!remove) { i = 0; diff --git a/set-contact-numbers.c b/set-contact-numbers.c index b3ecfb2..5b81d7e 100644 --- a/set-contact-numbers.c +++ b/set-contact-numbers.c @@ -1,141 +1,13 @@ /* See LICENSE file for copyright and license details. */ -#include "common.h" - -USAGE("[-C old-context] [-N old-number] [-F | -f] [-M | -m] ([-c new-context] [-n new-number] | -u) contact-id"); - - -int -main(int argc, char *argv[]) -{ - int set_facsimile = -1, set_mobile = -1, add = 1, edit = 0, remove = 0; - char *context = NULL, *number = NULL; - char *lookup_context = NULL, *lookup_number = NULL; - char *old_context = NULL, *old_number = NULL; - struct passwd *user; - struct libcontacts_contact contact; - struct libcontacts_number **r, **w; - size_t i; - - ARGBEGIN { - case 'C': - add = 0; - if (lookup_context) - usage(); - lookup_context = ARG(); - break; - case 'c': - edit = 1; - if (context) - usage(); - context = ARG(); - break; - case 'N': - add = 0; - if (lookup_number) - usage(); - lookup_number = ARG(); - break; - case 'n': - edit = 1; - if (number) - usage(); - number = ARG(); - 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 = 1; - break; - default: - usage(); - } ARGEND; - - if (remove == edit) { - if (edit) - usage(); - eprintf("at least one of -cnu is required\n"); - } +#define CATEGORY numbers - if (add) - edit = 0; +#define LIST_PARAMS(X)\ + X('C', "C", 'c', "c", context, "context")\ + X('N', "N", 'n', "n", number, "number") - if (argc != 0 || !*argv[0] || strchr(argv[0], '/')) - usage(); +#define LIST_BOOL_PARAMS(X)\ + X('F', "F", 'f', "f", facsimile, "facsimile")\ + X('M', "M", 'm', "m", mobile, "mobile") - 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 ((edit || remove) && contact.numbers) { - for (r = contact.numbers; *r; r++) { - if (lookup_context && strcmpnul((*r)->context, lookup_context)) - continue; - if (lookup_number && strcmpnul((*r)->context, lookup_number)) - continue; - break; - } - if (!edit) { - libcontacts_number_destroy(*r); - free(*r); - for (w = r++; (*w++ = *r++);); - } else if (*r) { - if (context) { - old_context = contact.numbers[i]->context; - contact.numbers[i]->context = context; - } - if (number) { - old_number = contact.numbers[i]->number; - contact.numbers[i]->number = number; - } - if (set_mobile >= 0) - contact.numbers[i]->is_mobile = set_mobile; - if (set_facsimile >= 0) - contact.numbers[i]->is_facsimile = set_facsimile; - } else { - libcontacts_contact_destroy(&contact); - return 0; - } - } else if (!edit && !remove) { - if (contact.numbers) - for (i = 0; contact.numbers[i]; i++); - 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 = context; - contact.numbers[i]->number = number; - contact.numbers[i]->is_mobile = set_mobile > 0; - contact.numbers[i]->is_facsimile = set_facsimile > 0; - } - - if (libcontacts_save_contact(&contact, user)) - eprintf("libcontacts_save_contact %s:", argv[0]); - - contact.numbers[i]->context = old_context; - contact.numbers[i]->number = old_number; - libcontacts_contact_destroy(&contact); - - return 0; -} +#include "common.h" +IMPLEMENT_SET_ON_LIST(number) diff --git a/set-contact-organisations.c b/set-contact-organisations.c index 733b8de..527e178 100644 --- a/set-contact-organisations.c +++ b/set-contact-organisations.c @@ -1,115 +1,9 @@ /* See LICENSE file for copyright and license details. */ -#include "common.h" - -USAGE("[-O old-organisation] [-T old-title] ([-o new-adress] [-t new-title] | -u) contact-id"); - - -int -main(int argc, char *argv[]) -{ - int add = 1, edit = 0, remove = 0; - char *organisation = NULL, *title = NULL; - char *lookup_organisation = NULL, *lookup_title = NULL; - char *old_organisation = NULL, *old_title = NULL; - struct passwd *user; - struct libcontacts_contact contact; - struct libcontacts_organisation **r, **w; - size_t i; - - ARGBEGIN { - case 'O': - add = 0; - if (lookup_organisation) - usage(); - lookup_organisation = ARG(); - break; - case 'o': - edit = 1; - if (organisation) - usage(); - organisation = ARG(); - break; - case 'T': - add = 0; - if (lookup_title) - usage(); - lookup_title = ARG(); - break; - case 't': - edit = 1; - if (title) - usage(); - title = ARG(); - break; - case 'u': - remove = 1; - break; - default: - usage(); - } ARGEND; - - if (remove == edit) { - if (edit) - usage(); - eprintf("at least one of -otu is required\n"); - } - - if (add) - edit = 0; +#define CATEGORY organisations - if (argc != 1 || !*argv[0] || strchr(argv[0], '/')) - usage(); +#define LIST_PARAMS(X)\ + X('O', "O", 'o', "o", organisation, "organisation")\ + X('T', "T", 't', "t", title, "title") - 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 ((edit || remove) && contact.organisations) { - for (r = contact.organisations; *r; r++) { - if (lookup_title && strcmpnul((*r)->title, lookup_title)) - continue; - if (lookup_organisation && strcmpnul((*r)->title, lookup_organisation)) - continue; - break; - } - if (!edit) { - libcontacts_organisation_destroy(*r); - free(*r); - for (w = r++; (*w++ = *r++);); - } else if (*r) { - if (title) { - old_title = contact.organisations[i]->title; - contact.organisations[i]->title = title; - } - if (organisation) { - old_organisation = contact.organisations[i]->organisation; - contact.organisations[i]->organisation = organisation; - } - } else { - libcontacts_contact_destroy(&contact); - return 0; - } - } else if (!edit && !remove) { - if (contact.organisations) - for (i = 0; contact.organisations[i]; i++); - contact.organisations = erealloc(contact.organisations, (i + 2) * sizeof(*contact.organisations)); - contact.organisations[i + 1] = NULL; - contact.organisations[i] = ecalloc(1, sizeof(**contact.organisations)); - contact.organisations[i]->title = title; - contact.organisations[i]->organisation = organisation; - } - - if (libcontacts_save_contact(&contact, user)) - eprintf("libcontacts_save_contact %s:", argv[0]); - - contact.organisations[i]->title = old_title; - contact.organisations[i]->organisation = old_organisation; - libcontacts_contact_destroy(&contact); - - return 0; -} +#include "common.h" +IMPLEMENT_SET_ON_LIST(organisation) diff --git a/set-contact-pgpkeys.c b/set-contact-pgpkeys.c index 93ad0ab..a221561 100644 --- a/set-contact-pgpkeys.c +++ b/set-contact-pgpkeys.c @@ -1,115 +1,9 @@ /* See LICENSE file for copyright and license details. */ -#include "common.h" - -USAGE("[-C old-context] [-F old-fingerprint] ([-c new-context] [-f new-fingerprint] | -u) contact-id"); - - -int -main(int argc, char *argv[]) -{ - int add = 1, edit = 0, remove = 0; - char *id = NULL, *context = NULL; - char *lookup_id = NULL, *lookup_context = NULL; - char *old_id = NULL, *old_context = NULL; - struct passwd *user; - struct libcontacts_contact contact; - struct libcontacts_pgpkey **r, **w; - size_t i; - - ARGBEGIN { - case 'C': - add = 0; - if (lookup_context) - usage(); - lookup_context = ARG(); - break; - case 'c': - edit = 0; - if (context) - usage(); - context = ARG(); - break; - case 'F': - add = 1; - if (lookup_id) - usage(); - lookup_id = ARG(); - break; - case 'f': - edit = 1; - if (id) - usage(); - id = ARG(); - break; - case 'u': - remove = 1; - break; - default: - usage(); - } ARGEND; - - if (remove == edit) { - if (edit) - usage(); - eprintf("at least one of -cfu is required\n"); - } - - if (add) - edit = 0; +#define CATEGORY pgpkeys - if (argc != 1 || !*argv[0] || strchr(argv[0], '/')) - usage(); +#define LIST_PARAMS(X)\ + X('C', "C", 'c', "c", context, "context")\ + X('F', "F", 'f', "f", id, "fingerprint") - 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 ((edit || remove) && contact.pgpkeys) { - for (r = contact.pgpkeys; *r; r++) { - if (lookup_context && strcmpnul((*r)->context, lookup_context)) - continue; - if (lookup_id && strcmpnul((*r)->context, lookup_id)) - continue; - break; - } - if (!edit) { - libcontacts_pgpkey_destroy(*r); - free(*r); - for (w = r++; (*w++ = *r++);); - } else if (*r) { - if (context) { - old_context = contact.pgpkeys[i]->context; - contact.pgpkeys[i]->context = context; - } - if (id) { - old_id = contact.pgpkeys[i]->id; - contact.pgpkeys[i]->id = id; - } - } else { - libcontacts_contact_destroy(&contact); - return 0; - } - } else if (!edit && !remove) { - if (contact.pgpkeys) - for (i = 0; contact.pgpkeys[i]; i++); - contact.pgpkeys = erealloc(contact.pgpkeys, (i + 2) * sizeof(*contact.pgpkeys)); - contact.pgpkeys[i + 1] = NULL; - contact.pgpkeys[i] = ecalloc(1, sizeof(**contact.pgpkeys)); - contact.pgpkeys[i]->context = context; - contact.pgpkeys[i]->id = id; - } - - if (libcontacts_save_contact(&contact, user)) - eprintf("libcontacts_save_contact %s:", argv[0]); - - contact.pgpkeys[i]->context = old_context; - contact.pgpkeys[i]->id = old_id; - libcontacts_contact_destroy(&contact); - - return 0; -} +#include "common.h" +IMPLEMENT_SET_ON_LIST(pgpkey) diff --git a/set-contact-photos.c b/set-contact-photos.c index 9c62d24..51366dd 100644 --- a/set-contact-photos.c +++ b/set-contact-photos.c @@ -1,7 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" -USAGE("[-ru] contact-id ... photo"); +USAGE("[-r | -u] contact-id ... photo"); static char * @@ -15,8 +15,13 @@ get_target(const char *path, size_t *lenp) if ((size_t)n == size) target = erealloc(target, size += 512); n = readlink(path, target, size); - if (n < 0) + if (n < 0) { + if (errno == EINVAL) { + free(target); + return NULL; + } eprintf("readlink %s:", path); + } } while ((size_t)n >= size); *lenp = (size_t)n; @@ -37,13 +42,13 @@ get_absolute_path(const char *path, const char *cwd) ret = emalloc(retlennul); memcpy(ret, path, retlennul); } else { - len1 = strlen(path); - len2 = strlen(cwd); + len1 = strlen(cwd); + len2 = strlen(path); retlennul = len1 + len2 + 2; ret = emalloc(retlennul); - memcpy(ret, path, len1); + memcpy(ret, cwd, len1); ret[len1++] = '/'; - memcpy(&ret[len1], cwd, ++len2); + memcpy(&ret[len1], path, ++len2); } again: @@ -157,15 +162,15 @@ main(int argc, char *argv[]) break; case 'u': remove = 1; - as_is = 1; break; default: usage(); } ARGEND; - if (argc < 2) + if (argc < 2 || (as_is & remove)) usage(); + as_is |= remove; photo = argv[--argc]; argv[argc] = NULL; @@ -195,7 +200,8 @@ main(int argc, char *argv[]) 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"); + weprintf("libcontacts_load_contact %s: %s\n", *argv, + errno ? strerror(errno) : "contact file is malformatted"); ret = 1; continue; } @@ -204,17 +210,15 @@ main(int argc, char *argv[]) if (!strcmp(contact.photos[i], photo)) break; r = &contact.photos[i]; + if (!remove && !*r) + goto add_photo; if (remove && *r) { free(*r); - for (w = r++; *r;) - *w++ = *r++; - *w = NULL; + for (w = r++; (*w++ = *r++);); if (libcontacts_save_contact(&contact, user)) { weprintf("libcontacts_save_contact %s:", *argv); ret = 1; } - } else if (!remove && !*r) { - goto add_photo; } } else if (!remove) { i = 0; diff --git a/set-contact-sites.c b/set-contact-sites.c index 6a9f60f..6add649 100644 --- a/set-contact-sites.c +++ b/set-contact-sites.c @@ -1,115 +1,9 @@ /* See LICENSE file for copyright and license details. */ -#include "common.h" - -USAGE("[-A old-address] [-C old-context] ([-a new-adress] [-c new-context] | -u) contact-id"); - - -int -main(int argc, char *argv[]) -{ - int add = 1, edit = 0, remove = 0; - char *address = NULL, *context = NULL; - char *lookup_address = NULL, *lookup_context = NULL; - char *old_address = NULL, *old_context = NULL; - struct passwd *user; - struct libcontacts_contact contact; - struct libcontacts_site **r, **w; - size_t i; - - ARGBEGIN { - case 'A': - add = 0; - if (lookup_address) - usage(); - lookup_address = ARG(); - break; - case 'a': - edit = 1; - if (address) - usage(); - address = ARG(); - break; - case 'C': - add = 0; - if (lookup_context) - usage(); - lookup_context = ARG(); - break; - case 'c': - edit = 1; - if (context) - usage(); - context = ARG(); - break; - case 'u': - remove = 1; - break; - default: - usage(); - } ARGEND; - - if (remove == edit) { - if (edit) - usage(); - eprintf("at least one of -acu is required\n"); - } - - if (add) - edit = 0; +#define CATEGORY sites - if (argc != 1 || !*argv[0] || strchr(argv[0], '/')) - usage(); +#define LIST_PARAMS(X)\ + X('A', "A", 'a', "a", address, "address")\ + X('C', "C", 'c', "c", context, "context") - 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 ((edit || remove) && contact.sites) { - for (r = contact.sites; *r; r++) { - if (lookup_context && strcmpnul((*r)->context, lookup_context)) - continue; - if (lookup_address && strcmpnul((*r)->context, lookup_address)) - continue; - break; - } - if (!edit) { - libcontacts_site_destroy(*r); - free(*r); - for (w = r++; (*w++ = *r++);); - } else if (*r) { - if (context) { - old_context = contact.sites[i]->context; - contact.sites[i]->context = context; - } - if (address) { - old_address = contact.sites[i]->address; - contact.sites[i]->address = address; - } - } else { - libcontacts_contact_destroy(&contact); - return 0; - } - } else if (!edit && !remove) { - if (contact.sites) - for (i = 0; contact.sites[i]; i++); - contact.sites = erealloc(contact.sites, (i + 2) * sizeof(*contact.sites)); - contact.sites[i + 1] = NULL; - contact.sites[i] = ecalloc(1, sizeof(**contact.sites)); - contact.sites[i]->context = context; - contact.sites[i]->address = address; - } - - if (libcontacts_save_contact(&contact, user)) - eprintf("libcontacts_save_contact %s:", argv[0]); - - contact.sites[i]->context = old_context; - contact.sites[i]->address = old_address; - libcontacts_contact_destroy(&contact); - - return 0; -} +#include "common.h" +IMPLEMENT_SET_ON_LIST(site) |