aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-04-12 13:37:59 +0200
committerMattias Andrée <maandree@kth.se>2021-04-12 13:37:59 +0200
commitfa88a28e46b7ac2d3dcd1938e5e4708157d08b22 (patch)
treec3ca4f98374328f37d71d1079f9e1f7406ed84d8
parentMinor fix to set-contact-photos (diff)
downloadcontacts-fa88a28e46b7ac2d3dcd1938e5e4708157d08b22.tar.gz
contacts-fa88a28e46b7ac2d3dcd1938e5e4708157d08b22.tar.bz2
contacts-fa88a28e46b7ac2d3dcd1938e5e4708157d08b22.tar.xz
Deduplicate code and make some small improvements
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--TODO13
-rw-r--r--add-contact.c26
-rw-r--r--common.h246
-rw-r--r--find-contact-by-chat.c80
-rw-r--r--find-contact-by-email.c64
-rw-r--r--find-contact-by-pgpkey.c64
-rw-r--r--find-contact-by-site.c64
-rw-r--r--get-contact-chats.c109
-rw-r--r--get-contact-emails.c91
-rw-r--r--get-contact-groups.c3
-rw-r--r--get-contact-organisations.c91
-rw-r--r--get-contact-pgpkeys.c91
-rw-r--r--get-contact-photos.c6
-rw-r--r--get-contact-sites.c91
-rw-r--r--set-contact-addresses.c6
15 files changed, 303 insertions, 742 deletions
diff --git a/TODO b/TODO
index fa80297..79237d6 100644
--- a/TODO
+++ b/TODO
@@ -1,16 +1,5 @@
-Test find-contact-by-chat
-Test find-contact-by-organisation
-Test find-contact-by-pgpkey
-Test find-contact-by-photo
-Test get-contact-blocks
-Test get-contact-chats
-Test get-contact-organisations
-Test get-contact-pgpkeys
-Test get-contact-photos
-Test list-chat-contacts
-Test list-contact-organisations
-Test list-organisation-contacts
Test set-contact-blocks
+Test get-contact-blocks
Test unblock-contact
Add ability to filter on unset values in entries
Add ability to remove values in entries
diff --git a/add-contact.c b/add-contact.c
index 843eb73..382d1a0 100644
--- a/add-contact.c
+++ b/add-contact.c
@@ -9,13 +9,29 @@ main(int argc, char *argv[])
{
struct passwd *user;
struct libcontacts_contact contact;
+ const char *id = NULL;
char *path;
int fd;
+ size_t i;
NOFLAGS(argc > 1);
- if (argc && (!*argv[0] || strchr(argv[0], '/')))
- usage();
+ if (argc) {
+ id = argv[0];
+ if (!id[0])
+ usage();
+ for (i = 0; id[i]; i++) {
+ if (id[i] == '/')
+ eprintf("contact-id cannot contain /\n");
+ else if (!islower(id[i]) && !isdigit(id[i]) && (i && id[i] != '.') && id[i] != '-')
+ if (id[i] != '~' || id[i + 1])
+ weprintf("it is recommended to only have [a-z0-9-] in contact-id\n");
+ }
+ if (id[i - 1] == '~')
+ eprintf("contact-id cannot end with ~\n");
+ if (id[0] == '.' && strcmp(id, ".me") && strcmp(id, ".groups"))
+ weprintf("it is recommended to only have [a-z0-9-] in contact-id\n");
+ }
errno = 0;
user = getpwuid(getuid());
@@ -26,10 +42,10 @@ main(int argc, char *argv[])
if (access(user->pw_dir, R_OK | W_OK | X_OK))
eprintf("access %s R_OK|W_OK|X_OK:", user->pw_dir);
- if (argc) {
- path = libcontacts_get_path(argv[0], user);
+ if (id) {
+ path = libcontacts_get_path(id, user);
if (!path)
- eprintf("libcontacts_get_path %s:", argv[0]);
+ eprintf("libcontacts_get_path %s:", id);
fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666);
if (fd < 0)
eprintf("open %s O_WRONLY|O_CREAT|O_EXCL 0666:", path);
diff --git a/common.h b/common.h
index d1345f5..d3f0f3e 100644
--- a/common.h
+++ b/common.h
@@ -32,22 +32,23 @@ int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, do
# define LIST_BOOL_PARAMS(X)
#endif
-#define X_USAGE_UPPER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+
+#define X_SET_USAGE_UPPER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
"[-"UPPERS" old-"DISPLAY"] "
-#define X_USAGE_LOWER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+#define X_SET_USAGE_LOWER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
"[-"LOWERS" new-"DISPLAY"] "
-#define X_USAGE_BOOL(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+#define X_SET_USAGE_BOOL(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
"[-"UPPERS" | -"LOWERS"] "
-#define X_PARAMS(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+#define X_SET_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)\
+#define X_SET_BOOL_PARAMS(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
int set_##VAR = -1;
-#define X_ARGPARSE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+#define X_SET_ARGPARSE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
case UPPERC:\
add = 0;\
if (lookup_##VAR)\
@@ -61,7 +62,7 @@ int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, do
VAR = ARG();\
break;
-#define X_BOOL_ARGPARSE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+#define X_SET_BOOL_ARGPARSE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
case UPPERC:\
if (set_##VAR >= 0)\
usage();\
@@ -73,50 +74,50 @@ int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, do
set_##VAR = 1;\
break;
-#define X_LOWER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+#define X_SET_LOWER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
LOWERS
-#define X_LOOKUP(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+#define X_SET_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)\
+#define X_SET_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)\
+#define X_SET_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)\
+#define X_SET_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)\
+#define X_SET_ADD(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
contact.CATEGORY[i]->VAR = VAR;
-#define X_RESTORE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+#define X_SET_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");\
+ USAGE(LIST_PARAMS(X_SET_USAGE_UPPER)LIST_BOOL_PARAMS(X_SET_USAGE_BOOL)"("LIST_PARAMS(X_SET_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)\
+ LIST_PARAMS(X_SET_PARAMS)\
+ LIST_BOOL_PARAMS(X_SET_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)\
+ LIST_PARAMS(X_SET_ARGPARSE)\
+ LIST_BOOL_PARAMS(X_SET_BOOL_ARGPARSE)\
case 'u':\
remove = 1;\
break;\
@@ -130,7 +131,7 @@ int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, do
if (remove == edit) {\
if (edit)\
usage();\
- eprintf("at least one of -"LIST_PARAMS(X_LOWER)"u is required\n");\
+ eprintf("at least one of -"LIST_PARAMS(X_SET_LOWER)"u is required\n");\
}\
\
if (add)\
@@ -149,8 +150,8 @@ int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, do
i = 0;\
if ((edit || remove) && contact.CATEGORY) {\
for (; contact.CATEGORY[i]; i++) {\
- LIST_PARAMS(X_LOOKUP)\
- LIST_BOOL_PARAMS(X_BOOL_LOOKUP)\
+ LIST_PARAMS(X_SET_LOOKUP)\
+ LIST_BOOL_PARAMS(X_SET_BOOL_LOOKUP)\
break;\
}\
if (!contact.CATEGORY[i]) {\
@@ -162,8 +163,8 @@ int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, do
free(*r);\
for (w = r++; (*w++ = *r++););\
} else {\
- LIST_PARAMS(X_CHANGE)\
- LIST_BOOL_PARAMS(X_BOOL_SET)\
+ LIST_PARAMS(X_SET_CHANGE)\
+ LIST_BOOL_PARAMS(X_SET_BOOL_SET)\
}\
} else if (!edit && !remove) {\
if (contact.CATEGORY)\
@@ -171,17 +172,208 @@ int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, do
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)\
+ LIST_PARAMS(X_SET_ADD)\
+ LIST_BOOL_PARAMS(X_SET_BOOL_SET)\
}\
\
if (libcontacts_save_contact(&contact, user))\
eprintf("libcontacts_save_contact %s:", argv[0]);\
\
if (!r) {\
- LIST_PARAMS(X_RESTORE)\
+ LIST_PARAMS(X_SET_RESTORE)\
}\
\
libcontacts_contact_destroy(&contact);\
return 0;\
}
+
+
+#define X_GET_USAGE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+ "[-"LOWERS" "DISPLAY"] "
+
+#define X_GET_UPPER(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+ UPPERS
+
+#define X_GET_PARAMS(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+ int display_##VAR = 0;\
+ const char *lookup_##VAR = NULL;
+
+#define X_GET_ARGPARSE(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+ case LOWERC:\
+ if (lookup_##VAR)\
+ usage();\
+ lookup_##VAR = ARG();\
+ break;\
+ case UPPERC:\
+ fields += !display_##VAR;\
+ display_##VAR = 1;\
+ break;
+
+#define X_GET_AUTO_DISPLAY(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+ fields += display_##VAR = !lookup_##VAR;
+
+#define X_GET_LOOKUP(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+ if (lookup_##VAR && strcmpnul(elem->VAR, lookup_##VAR))\
+ continue;
+
+#define X_GET_FULL_LOOKUP(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+ lookup_##VAR &&
+
+#define X_GET_DISPLAY(UPPERC, UPPERS, LOWERC, LOWERS, VAR, DISPLAY)\
+ if (display_##VAR) {\
+ fields_ -= 1;\
+ printf("%s%s", elem->VAR, fields_ ? ": " : "\n");\
+ }
+
+#define IMPLEMENT_GET_ON_LIST(CAT)\
+ USAGE(LIST_PARAMS(X_GET_USAGE)"[-"LIST_PARAMS(X_GET_UPPER)"] contact-id ..."); \
+ \
+ int\
+ main(int argc, char *argv[])\
+ {\
+ LIST_PARAMS(X_GET_PARAMS)\
+ struct passwd *user;\
+ struct libcontacts_contact contact;\
+ struct libcontacts_##CAT **elems, *elem;\
+ int ret = 0, fields = 0, fields_;\
+ size_t i; \
+ \
+ ARGBEGIN {\
+ LIST_PARAMS(X_GET_ARGPARSE)\
+ default:\
+ usage();\
+ } ARGEND;\
+ \
+ if (!argc)\
+ usage();\
+ \
+ if (!fields) {\
+ LIST_PARAMS(X_GET_AUTO_DISPLAY)\
+ }\
+ \
+ 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 ((elems = contact.CATEGORY)) {\
+ for (; (elem = *elems); elems++) {\
+ LIST_PARAMS(X_GET_LOOKUP)\
+ if (LIST_PARAMS(X_GET_FULL_LOOKUP) !fields) {\
+ printf("%s\n", *argv);\
+ continue;\
+ }\
+ if (argc > 1)\
+ printf("%s: ", *argv);\
+ fields_ = fields;\
+ LIST_PARAMS(X_GET_DISPLAY)\
+ }\
+ }\
+ libcontacts_contact_destroy(&contact);\
+ }\
+ \
+ if (fflush(stdout) || ferror(stdout) || fclose(stdout))\
+ eprintf("printf:");\
+ return ret;\
+ }
+
+
+#define X_FIND_USAGE(LOWERC, LOWERS, VAR, DISPLAY)\
+ "[-"LOWERS" "DISPLAY"] "
+
+#define X_FIND_PARAMS(LOWERC, LOWERS, VAR, DISPLAY)\
+ const char *VAR = NULL;
+
+#define X_FIND_ARGPARSE(LOWERC, LOWERS, VAR, DISPLAY)\
+ case LOWERC:\
+ if (VAR)\
+ usage();\
+ VAR = ARG();\
+ break;
+
+#define X_FIND_LOOKUP(LOWERC, LOWERS, VAR, DISPLAY)\
+ if (VAR && strcmpnul(elem->VAR, VAR))\
+ continue;
+
+#ifdef SUBCATEGORY
+# define PRINT_PREFIX_LIST(DATUM)\
+ if (elem->SUBCATEGORY && !SUBCATEGORY)\
+ printf("%s (%s: %s)\n", contacts[i]->id, elem->SUBCATEGORY, elem->DATUM);\
+ else
+# define PRINT_PREFIX_LOOKUP(DATUM)\
+ if (elem->SUBCATEGORY && !SUBCATEGORY)\
+ printf("%s (%s)\n", contacts[i]->id, elem->SUBCATEGORY);\
+ else
+#else
+# define PRINT_PREFIX_LIST(DATUM)
+# define PRINT_PREFIX_LOOKUP(DATUM)
+#endif
+
+#define IMPLEMENT_FIND_ON_LIST(CAT, DATUM, DISPLAY)\
+ USAGE(LIST_PARAMS(X_FIND_USAGE)"(-L | "DISPLAY")");\
+ \
+ int\
+ main(int argc, char *argv[])\
+ {\
+ int list = 0;\
+ LIST_PARAMS(X_FIND_PARAMS)\
+ struct passwd *user;\
+ struct libcontacts_contact **contacts;\
+ struct libcontacts_##CAT **elems, *elem;\
+ size_t i;\
+ \
+ ARGBEGIN {\
+ LIST_PARAMS(X_FIND_ARGPARSE)\
+ case 'L':\
+ list = 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, 1))\
+ eprintf("libcontacts_load_contacts:");\
+ for (i = 0; contacts[i]; i++) {\
+ if ((elems = contacts[i]->CATEGORY)) {\
+ for (; (elem = *elems); elems++) {\
+ if (!elem->DATUM)\
+ continue;\
+ LIST_PARAMS(X_FIND_LOOKUP)\
+ if (list) {\
+ PRINT_PREFIX_LIST(DATUM)\
+ printf("%s (%s)\n", contacts[i]->id, elem->DATUM);\
+ } else if (!strcmp(elem->DATUM, argv[0])) {\
+ PRINT_PREFIX_LOOKUP(DATUM)\
+ 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/find-contact-by-chat.c b/find-contact-by-chat.c
index 1a060aa..67ebfd1 100644
--- a/find-contact-by-chat.c
+++ b/find-contact-by-chat.c
@@ -1,76 +1,10 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-c context] [-s service] (-L | address)");
-
-
-int
-main(int argc, char *argv[])
-{
- int list = 0;
- struct passwd *user;
- struct libcontacts_contact **contacts;
- struct libcontacts_chat **chats, *chat;
- char *context = NULL, *service = NULL;
- size_t i;
-
- ARGBEGIN {
- case 'c':
- if (context)
- usage();
- context = ARG();
- break;
- case 's':
- if (service)
- usage();
- service = ARG();
- break;
- case 'L':
- list = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY chats
+#define SUBCATEGORY service
- if (argc != 1 - list)
- usage();
+#define LIST_PARAMS(X)\
+ X('c', "c", context, "context")\
+ X('s', "s", service, "service")
- errno = 0;
- user = getpwuid(getuid());
- if (!user)
- eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist");
-
- if (libcontacts_load_contacts(&contacts, user, 1))
- eprintf("libcontacts_load_contacts:");
- for (i = 0; contacts[i]; i++) {
- if ((chats = contacts[i]->chats)) {
- for (; (chat = *chats); chats++) {
- if (!chat->address)
- continue;
- if (context && strcmpnul(chat->context, context))
- continue;
- if (service && strcmpnul(chat->service, service))
- continue;
- if (list) {
- if (chat->service && !service)
- printf("%s (%s: %s)\n", contacts[i]->id, chat->service, chat->address);
- else
- printf("%s (%s)\n", contacts[i]->id, chat->address);
- } else if (!strcmp(chat->address, argv[0])) {
- if (chat->service && !service)
- printf("%s (%s)\n", contacts[i]->id, chat->service);
- else
- 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;
-}
+#include "common.h"
+IMPLEMENT_FIND_ON_LIST(chat, address, "address")
diff --git a/find-contact-by-email.c b/find-contact-by-email.c
index accdf3b..0e05c60 100644
--- a/find-contact-by-email.c
+++ b/find-contact-by-email.c
@@ -1,62 +1,8 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-c context] (-L | address)");
-
-
-int
-main(int argc, char *argv[])
-{
- int list = 0;
- struct passwd *user;
- struct libcontacts_contact **contacts;
- struct libcontacts_email **emails, *email;
- char *context = NULL;
- size_t i;
-
- ARGBEGIN {
- case 'c':
- if (context)
- usage();
- context = ARG();
- break;
- case 'L':
- list = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY emails
- if (argc != 1 - list)
- usage();
+#define LIST_PARAMS(X)\
+ X('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_contacts(&contacts, user, 1))
- eprintf("libcontacts_load_contacts:");
- for (i = 0; contacts[i]; i++) {
- if ((emails = contacts[i]->emails)) {
- for (; (email = *emails); emails++) {
- if (!email->address)
- continue;
- if (context && strcmpnul(email->context, context))
- continue;
- if (list)
- printf("%s (%s)\n", contacts[i]->id, email->address);
- else if (!strcmp(email->address, argv[0]))
- 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;
-}
+#include "common.h"
+IMPLEMENT_FIND_ON_LIST(email, address, "address")
diff --git a/find-contact-by-pgpkey.c b/find-contact-by-pgpkey.c
index e8fbe8e..632cef3 100644
--- a/find-contact-by-pgpkey.c
+++ b/find-contact-by-pgpkey.c
@@ -1,62 +1,8 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-c context] (-L | fingerprint)");
-
-
-int
-main(int argc, char *argv[])
-{
- int list = 0;
- struct passwd *user;
- struct libcontacts_contact **contacts;
- struct libcontacts_pgpkey **pgpkeys, *pgpkey;
- char *context = NULL;
- size_t i;
-
- ARGBEGIN {
- case 'c':
- if (context)
- usage();
- context = ARG();
- break;
- case 'L':
- list = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY pgpkeys
- if (argc != 1 - list)
- usage();
+#define LIST_PARAMS(X)\
+ X('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_contacts(&contacts, user, 1))
- eprintf("libcontacts_load_contacts:");
- for (i = 0; contacts[i]; i++) {
- if ((pgpkeys = contacts[i]->pgpkeys)) {
- for (; (pgpkey = *pgpkeys); pgpkeys++) {
- if (!pgpkey->id)
- continue;
- if (context && strcmpnul(pgpkey->context, context))
- continue;
- if (list)
- printf("%s (%s)\n", contacts[i]->id, pgpkey->id);
- else if (!strcmp(pgpkey->id, argv[0]))
- 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;
-}
+#include "common.h"
+IMPLEMENT_FIND_ON_LIST(pgpkey, id, "fingerprint")
diff --git a/find-contact-by-site.c b/find-contact-by-site.c
index 616a828..b19c027 100644
--- a/find-contact-by-site.c
+++ b/find-contact-by-site.c
@@ -1,62 +1,8 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-c context] (-L | address)");
-
-
-int
-main(int argc, char *argv[])
-{
- int list = 0;
- struct passwd *user;
- struct libcontacts_contact **contacts;
- struct libcontacts_site **sites, *site;
- char *context = NULL;
- size_t i;
-
- ARGBEGIN {
- case 'c':
- if (context)
- usage();
- context = ARG();
- break;
- case 'L':
- list = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY sites
- if (argc != 1 - list)
- usage();
+#define LIST_PARAMS(X)\
+ X('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_contacts(&contacts, user, 1))
- eprintf("libcontacts_load_contacts:");
- for (i = 0; contacts[i]; i++) {
- if ((sites = contacts[i]->sites)) {
- for (; (site = *sites); sites++) {
- if (!site->address)
- continue;
- if (context && strcmpnul(site->context, context))
- continue;
- if (list)
- printf("%s (%s)\n", contacts[i]->id, site->address);
- else if (!strcmp(site->address, argv[0]))
- 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;
-}
+#include "common.h"
+IMPLEMENT_FIND_ON_LIST(site, address, "address")
diff --git a/get-contact-chats.c b/get-contact-chats.c
index 5e790d7..fecb152 100644
--- a/get-contact-chats.c
+++ b/get-contact-chats.c
@@ -1,105 +1,10 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-a address] [-c context] [-s service] [-ACS] contact-id ...");
-
-
-int
-main(int argc, char *argv[])
-{
- int display_ctx = 0, display_addr = 0, display_srv = 0;
- const char *lookup_ctx = NULL, *lookup_addr = NULL, *lookup_srv = NULL;
- struct passwd *user;
- struct libcontacts_contact contact;
- struct libcontacts_chat **chats, *chat;
- int ret = 0;
- size_t i;
-
- ARGBEGIN {
- case 'a':
- if (lookup_addr)
- usage();
- lookup_addr = ARG();
- break;
- case 'c':
- if (lookup_ctx)
- usage();
- lookup_ctx = ARG();
- break;
- case 's':
- if (lookup_srv)
- usage();
- lookup_srv = ARG();
- break;
- case 'A':
- display_addr = 1;
- break;
- case 'C':
- display_ctx = 1;
- break;
- case 'S':
- display_srv = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY chats
- if (!argc)
- usage();
+#define LIST_PARAMS(X)\
+ X('C', "C", 'c', "c", context, "context")\
+ X('S', "S", 's', "s", service, "service")\
+ X('A', "A", 'a', "a", address, "address")
- if (!display_ctx && !display_addr && !display_srv) {
- display_ctx = !lookup_ctx;
- display_addr = !lookup_addr;
- display_srv = !lookup_srv;
- }
-
- 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 ((chats = contact.chats)) {
- for (; (chat = *chats); chats++) {
- if (lookup_ctx && strcmpnul(chat->context, lookup_ctx))
- continue;
- if (lookup_addr && strcmpnul(chat->address, lookup_addr))
- continue;
- if (lookup_srv && strcmpnul(chat->service, lookup_srv))
- continue;
- if (!display_ctx && !display_addr && !display_srv) {
- printf("%s\n", *argv);
- continue;
- }
- if (display_ctx && !chat->context)
- continue;
- if (display_srv && !chat->service)
- continue;
- if (display_addr && !chat->address)
- continue;
- if (argc > 1)
- printf("%s: ", *argv);
- if (display_ctx)
- printf("%s%s", chat->context, (display_srv || display_addr) ? ": " : "\n");
- if (display_srv)
- printf("%s%s", chat->service, display_addr ? ": " : "\n");
- if (display_addr)
- printf("%s\n", chat->address);
- }
- }
- libcontacts_contact_destroy(&contact);
- }
-
- if (fflush(stdout) || ferror(stdout) || fclose(stdout))
- eprintf("printf:");
- return ret;
-}
+#include "common.h"
+IMPLEMENT_GET_ON_LIST(chat)
diff --git a/get-contact-emails.c b/get-contact-emails.c
index a672b0a..e859669 100644
--- a/get-contact-emails.c
+++ b/get-contact-emails.c
@@ -1,88 +1,9 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-a address] [-c context] [-AC] contact-id ...");
-
-
-int
-main(int argc, char *argv[])
-{
- int display_ctx = 0, display_addr = 0;
- const char *lookup_ctx = NULL, *lookup_addr = NULL;
- struct passwd *user;
- struct libcontacts_contact contact;
- struct libcontacts_email **emails, *email;
- int ret = 0;
- size_t i;
-
- ARGBEGIN {
- case 'a':
- if (lookup_addr)
- usage();
- lookup_addr = ARG();
- break;
- case 'c':
- if (lookup_ctx)
- usage();
- lookup_ctx = ARG();
- break;
- case 'A':
- display_addr = 1;
- break;
- case 'C':
- display_ctx = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY emails
- if (!argc)
- usage();
+#define LIST_PARAMS(X)\
+ X('C', "C", 'c', "c", context, "context")\
+ X('A', "A", 'a', "a", address, "address")
- if (lookup_ctx && !lookup_addr && !display_ctx && !display_addr)
- display_addr = 1;
- if (lookup_addr && !lookup_ctx && !display_ctx && !display_addr)
- display_ctx = 1;
-
- 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 ((emails = contact.emails)) {
- for (; (email = *emails); emails++) {
- if (lookup_ctx && strcmpnul(email->context, lookup_ctx))
- continue;
- if (lookup_addr && strcmpnul(email->address, lookup_addr))
- continue;
- if (lookup_ctx && lookup_addr && !display_ctx && !display_addr) {
- printf("%s\n", *argv);
- continue;
- }
- if (argc > 1)
- printf("%s: ", *argv);
- if (!display_ctx == !display_addr)
- printf("%s: %s\n", email->context, email->address);
- else if (display_addr)
- printf("%s\n", email->address);
- else
- printf("%s\n", email->context);
- }
- }
- libcontacts_contact_destroy(&contact);
- }
-
- if (fflush(stdout) || ferror(stdout) || fclose(stdout))
- eprintf("printf:");
- return ret;
-}
+#include "common.h"
+IMPLEMENT_GET_ON_LIST(email)
diff --git a/get-contact-groups.c b/get-contact-groups.c
index 35c898b..de71918 100644
--- a/get-contact-groups.c
+++ b/get-contact-groups.c
@@ -42,7 +42,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;
}
if (lookup_unassigned) {
diff --git a/get-contact-organisations.c b/get-contact-organisations.c
index 92be776..dc5228e 100644
--- a/get-contact-organisations.c
+++ b/get-contact-organisations.c
@@ -1,88 +1,9 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-o organisation] [-t title] [-OT] contact-id ...");
-
-
-int
-main(int argc, char *argv[])
-{
- int display_org = 0, display_title = 0;
- const char *lookup_org = NULL, *lookup_title = NULL;
- struct passwd *user;
- struct libcontacts_contact contact;
- struct libcontacts_organisation **orgs, *org;
- int ret = 0;
- size_t i;
-
- ARGBEGIN {
- case 'o':
- if (lookup_org)
- usage();
- lookup_org = ARG();
- break;
- case 't':
- if (lookup_title)
- usage();
- lookup_title = ARG();
- break;
- case 'O':
- display_org = 1;
- break;
- case 'T':
- display_title = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY organisations
- if (!argc)
- usage();
+#define LIST_PARAMS(X)\
+ X('O', "O", 'o', "o", organisation, "organisation")\
+ X('T', "T", 't', "t", title, "title")
- if (lookup_org && !lookup_title && !display_org && !display_title)
- display_title = 1;
- if (lookup_title && !lookup_org && !display_org && !display_title)
- display_org = 1;
-
- 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 ((orgs = contact.organisations)) {
- for (; (org = *orgs); orgs++) {
- if (lookup_org && strcmpnul(org->organisation, lookup_org))
- continue;
- if (lookup_title && strcmpnul(org->title, lookup_title))
- continue;
- if (lookup_org && lookup_title && !display_org && !display_title) {
- printf("%s\n", *argv);
- continue;
- }
- if (argc > 1)
- printf("%s: ", *argv);
- if (!display_org == !display_title)
- printf("%s: %s\n", org->organisation, org->title);
- else if (display_title)
- printf("%s\n", org->title);
- else
- printf("%s\n", org->organisation);
- }
- }
- libcontacts_contact_destroy(&contact);
- }
-
- if (fflush(stdout) || ferror(stdout) || fclose(stdout))
- eprintf("printf:");
- return ret;
-}
+#include "common.h"
+IMPLEMENT_GET_ON_LIST(organisation)
diff --git a/get-contact-pgpkeys.c b/get-contact-pgpkeys.c
index e0a3961..28586d0 100644
--- a/get-contact-pgpkeys.c
+++ b/get-contact-pgpkeys.c
@@ -1,88 +1,9 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-c context] [-f fingerprint] [-CF] contact-id ...");
-
-
-int
-main(int argc, char *argv[])
-{
- int display_ctx = 0, display_id = 0;
- const char *lookup_ctx = NULL, *lookup_id = NULL;
- struct passwd *user;
- struct libcontacts_contact contact;
- struct libcontacts_pgpkey **keys, *key;
- int ret = 0;
- size_t i;
-
- ARGBEGIN {
- case 'c':
- if (lookup_ctx)
- usage();
- lookup_ctx = ARG();
- break;
- case 'f':
- if (lookup_id)
- usage();
- lookup_id = ARG();
- break;
- case 'C':
- display_ctx = 1;
- break;
- case 'F':
- display_id = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY pgpkeys
- if (!argc)
- usage();
+#define LIST_PARAMS(X)\
+ X('C', "C", 'c', "c", context, "context")\
+ X('F', "F", 'f', "f", id, "fingerprint")
- if (lookup_ctx && !lookup_id && !display_ctx && !display_id)
- display_id = 1;
- if (lookup_id && !lookup_ctx && !display_ctx && !display_id)
- display_ctx = 1;
-
- 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 ((keys = contact.pgpkeys)) {
- for (; (key = *keys); keys++) {
- if (lookup_ctx && strcmpnul(key->context, lookup_ctx))
- continue;
- if (lookup_id && strcmpnul(key->id, lookup_id))
- continue;
- if (lookup_ctx && lookup_id && !display_ctx && !display_id) {
- printf("%s\n", *argv);
- continue;
- }
- if (argc > 1)
- printf("%s: ", *argv);
- if (!display_ctx == !display_id)
- printf("%s: %s\n", key->context, key->id);
- else if (display_id)
- printf("%s\n", key->id);
- else
- printf("%s\n", key->context);
- }
- }
- libcontacts_contact_destroy(&contact);
- }
-
- if (fflush(stdout) || ferror(stdout) || fclose(stdout))
- eprintf("printf:");
- return ret;
-}
+#include "common.h"
+IMPLEMENT_GET_ON_LIST(pgpkey)
diff --git a/get-contact-photos.c b/get-contact-photos.c
index 3b44393..115c776 100644
--- a/get-contact-photos.c
+++ b/get-contact-photos.c
@@ -45,8 +45,10 @@ main(int argc, char *argv[])
}
for (; *argv; argv++) {
- if (libcontacts_load_contact(*argv, &contact, user))
- eprintf("libcontacts_load_contact %s: %s\n", *argv, errno ? strerror(errno) : "contact file is malformatted");
+ if (libcontacts_load_contact(*argv, &contact, user)) {
+ eprintf("libcontacts_load_contact %s: %s\n", *argv,
+ errno ? strerror(errno) : "contact file is malformatted");
+ }
if (!contact.photos) {
libcontacts_contact_destroy(&contact);
for (i = 0; photos[i]; i++)
diff --git a/get-contact-sites.c b/get-contact-sites.c
index 4bd53e6..ae1356a 100644
--- a/get-contact-sites.c
+++ b/get-contact-sites.c
@@ -1,88 +1,9 @@
/* See LICENSE file for copyright and license details. */
-#include "common.h"
-
-USAGE("[-a address] [-c context] [-AC] contact-id ...");
-
-
-int
-main(int argc, char *argv[])
-{
- int display_ctx = 0, display_addr = 0;
- const char *lookup_ctx = NULL, *lookup_addr = NULL;
- struct passwd *user;
- struct libcontacts_contact contact;
- struct libcontacts_site **sites, *site;
- int ret = 0;
- size_t i;
-
- ARGBEGIN {
- case 'a':
- if (lookup_addr)
- usage();
- lookup_addr = ARG();
- break;
- case 'c':
- if (lookup_ctx)
- usage();
- lookup_ctx = ARG();
- break;
- case 'A':
- display_addr = 1;
- break;
- case 'C':
- display_ctx = 1;
- break;
- default:
- usage();
- } ARGEND;
+#define CATEGORY sites
- if (!argc)
- usage();
+#define LIST_PARAMS(X)\
+ X('C', "C", 'c', "c", context, "context")\
+ X('A', "A", 'a', "a", address, "address")
- if (lookup_ctx && !lookup_addr && !display_ctx && !display_addr)
- display_addr = 1;
- if (lookup_addr && !lookup_ctx && !display_ctx && !display_addr)
- display_ctx = 1;
-
- 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 ((sites = contact.sites)) {
- for (; (site = *sites); sites++) {
- if (lookup_ctx && strcmpnul(site->context, lookup_ctx))
- continue;
- if (lookup_addr && strcmpnul(site->address, lookup_addr))
- continue;
- if (lookup_ctx && lookup_addr && !display_ctx && !display_addr) {
- printf("%s\n", *argv);
- continue;
- }
- if (argc > 1)
- printf("%s: ", *argv);
- if (!display_ctx == !display_addr)
- printf("%s: %s\n", site->context, site->address);
- else if (display_addr)
- printf("%s\n", site->address);
- else
- printf("%s\n", site->context);
- }
- }
- libcontacts_contact_destroy(&contact);
- }
-
- if (fflush(stdout) || ferror(stdout) || fclose(stdout))
- eprintf("printf:");
- return ret;
-}
+#include "common.h"
+IMPLEMENT_GET_ON_LIST(site)
diff --git a/set-contact-addresses.c b/set-contact-addresses.c
index 9c50637..ff40342 100644
--- a/set-contact-addresses.c
+++ b/set-contact-addresses.c
@@ -129,6 +129,9 @@ main(int argc, char *argv[])
if (lookup_location && parse_coord(lookup_location, &flat, &lat_min, &lat_max, &flon, &lon_min, &lon_max))
usage();
+ if (argc != 1 || !*argv[0] || strchr(argv[0], '/'))
+ usage();
+
if (remove == edit) {
if (edit)
usage();
@@ -138,9 +141,6 @@ main(int argc, char *argv[])
if (add)
edit = 0;
- if (argc != 1 || !*argv[0] || strchr(argv[0], '/'))
- usage();
-
errno = 0;
user = getpwuid(getuid());
if (!user)