diff options
Diffstat (limited to '')
-rw-r--r-- | .gitignore | 9 | ||||
-rw-r--r-- | Makefile | 22 | ||||
-rw-r--r-- | TODO | 8 | ||||
-rw-r--r-- | find-contact-by-organisation.c | 79 | ||||
-rw-r--r-- | get-contact-emails.c | 8 | ||||
-rw-r--r-- | get-contact-groups.c | 68 | ||||
-rw-r--r-- | get-contact-organisations.c | 8 | ||||
-rw-r--r-- | get-contact-pgpkeys.c | 8 | ||||
-rw-r--r-- | get-contact-sites.c | 8 | ||||
-rw-r--r-- | list-contact-groups.c | 106 | ||||
-rw-r--r-- | list-contact-organisations.c | 117 | ||||
-rw-r--r-- | list-group-contacts.c | 46 | ||||
-rw-r--r-- | list-organisation-contacts.c | 58 | ||||
-rw-r--r-- | set-contact-gender.c | 6 | ||||
-rw-r--r-- | set-contact-groups.c | 79 |
15 files changed, 610 insertions, 20 deletions
@@ -7,29 +7,34 @@ *.su *.lo *.bo +/contacts +/contacts.c /find-contact-by-email /find-contact-by-name +/find-contact-by-organisation /find-contact-by-pgpkey /find-contact-by-site /get-contact-emails /get-contact-file /get-contact-gender +/get-contact-groups /get-contact-name /get-contact-notes /get-contact-organisations /get-contact-pgpkeys /get-contact-sites /is-contact-ice +/list-contact-groups /list-contact-organisations /list-contacts +/list-group-contacts /list-organisation-contacts /set-contact-emails /set-contact-gender +/set-contact-groups /set-contact-ice /set-contact-name /set-contact-notes /set-contact-organisations /set-contact-pgpkeys /set-contact-sites -/contacts -/contacts.c @@ -7,20 +7,27 @@ include $(CONFIGFILE) BIN =\ find-contact-by-email\ find-contact-by-name\ + find-contact-by-organisation\ find-contact-by-pgpkey\ find-contact-by-site\ get-contact-emails\ get-contact-file\ get-contact-gender\ + get-contact-groups\ get-contact-name\ get-contact-notes\ get-contact-organisations\ get-contact-pgpkeys\ get-contact-sites\ is-contact-ice\ + list-contact-groups\ + list-contact-organisations\ list-contacts\ + list-group-contacts\ + list-organisation-contacts\ set-contact-emails\ set-contact-gender\ + set-contact-groups\ set-contact-ice\ set-contact-name\ set-contact-notes\ @@ -60,6 +67,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-organisation: find-contact-by-organisation.o + $(CC) -o $@ $@.o $(LDFLAGS) + find-contact-by-pgpkey: find-contact-by-pgpkey.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -75,6 +85,9 @@ get-contact-file: get-contact-file.o get-contact-gender: get-contact-gender.o $(CC) -o $@ $@.o $(LDFLAGS) +get-contact-groups: get-contact-groups.o + $(CC) -o $@ $@.o $(LDFLAGS) + get-contact-name: get-contact-name.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -93,12 +106,18 @@ get-contact-sites: get-contact-sites.o is-contact-ice: is-contact-ice.o $(CC) -o $@ $@.o $(LDFLAGS) +list-contact-groups: list-contact-groups.o + $(CC) -o $@ $@.o $(LDFLAGS) + list-contact-organisations: list-contact-organisations.o $(CC) -o $@ $@.o $(LDFLAGS) list-contacts: list-contacts.o $(CC) -o $@ $@.o $(LDFLAGS) +list-group-contacts: list-group-contacts.o + $(CC) -o $@ $@.o $(LDFLAGS) + list-organisation-contacts: list-organisation-contacts.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -108,6 +127,9 @@ set-contact-emails: set-contact-emails.o set-contact-gender: set-contact-gender.o $(CC) -o $@ $@.o $(LDFLAGS) +set-contact-groups: set-contact-groups.o + $(CC) -o $@ $@.o $(LDFLAGS) + set-contact-ice: set-contact-ice.o $(CC) -o $@ $@.o $(LDFLAGS) @@ -1,18 +1,17 @@ -list-contact-organisations -list-organisation-contacts - Add tools for .photos -Add tools for .groups Add tools for .blocks Add tools for .numbers Add tools for .addresses Add tools for .chats Add tools for .birthday + Test find-contact-by-email Test find-contact-by-name +Test find-contact-by-organisation Test find-contact-by-pgpkey Test find-contact-by-site Test get-contact-emails +Test get-contact-groups Test get-contact-name Test get-contact-organisations Test get-contact-pgpkeys @@ -20,6 +19,7 @@ Test get-contact-sites Test list-contact-organisations Test list-organisation-contacts Test set-contact-emails +Test set-contact-groups Test set-contact-name Test set-contact-organisations Test set-contact-pgpkeys diff --git a/find-contact-by-organisation.c b/find-contact-by-organisation.c new file mode 100644 index 0000000..8287225 --- /dev/null +++ b/find-contact-by-organisation.c @@ -0,0 +1,79 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-o organisation] [-t title] [-OT]"); + + +int +main(int argc, char *argv[]) +{ + int display_organisation = 0, display_title = 0; + struct passwd *user; + struct libcontacts_contact **contacts; + struct libcontacts_organisation **orgs, *org; + char *organisation = NULL, *title = NULL; + size_t i; + + ARGBEGIN { + case 'o': + if (organisation) + usage(); + organisation = ARG(); + break; + case 't': + if (title) + usage(); + title = ARG(); + break; + case 'O': + display_organisation = 1; + break; + case 'T': + display_title = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + if (!organisation && !title && !display_organisation && !display_title) + display_organisation = 1; + + 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 ((orgs = contacts[i]->organisations)) { + for (; (org = *orgs); orgs++) { + if (organisation && strcmpnul(org->organisation, organisation)) + continue; + if (title && strcmpnul(org->title, title)) + continue; + if (display_organisation && display_title) { + printf("%s (%s: %s)\n", contacts[i]->id, org->organisation, org->title); + } else if (display_organisation) { + printf("%s (%s)\n", contacts[i]->id, org->organisation); + } else if (display_title) { + printf("%s (%s)\n", contacts[i]->id, org->title); + } else { + printf("%s\n", contacts[i]->id); + break; + } + } + } + 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-emails.c b/get-contact-emails.c index 891c873..c41b48f 100644 --- a/get-contact-emails.c +++ b/get-contact-emails.c @@ -57,8 +57,10 @@ main(int argc, char *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 { - for (emails = contact.emails; (email = *emails); emails++) { + 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)) @@ -76,8 +78,8 @@ main(int argc, char *argv[]) else printf("%s\n", email->context); } - libcontacts_contact_destroy(&contact); } + libcontacts_contact_destroy(&contact); } if (fflush(stdout) || ferror(stdout) || fclose(stdout)) diff --git a/get-contact-groups.c b/get-contact-groups.c new file mode 100644 index 0000000..fa1eb77 --- /dev/null +++ b/get-contact-groups.c @@ -0,0 +1,68 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-g group | -n] contact-id ..."); + + +int +main(int argc, char *argv[]) +{ + int lookup_unassigned = 0; + struct passwd *user; + struct libcontacts_contact contact; + char *lookup_group = NULL; + char **groups; + int ret = 0; + size_t i; + + ARGBEGIN { + case 'g': + if (lookup_group) + usage(); + lookup_group = ARG(); + break; + case 'n': + lookup_unassigned = 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; + } + if (lookup_unassigned) { + if (!contact.groups || !*contact.groups) + printf("%s\n", *argv); + } else if ((groups = contact.groups)) { + for (; *groups; groups++) { + if (lookup_group) { + printf("%s\n", *argv); + } else { + if (argc > 1) + printf("%s: ", *argv); + printf("%s\n", *groups); + } + } + } + libcontacts_contact_destroy(&contact); + } + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + return ret; +} diff --git a/get-contact-organisations.c b/get-contact-organisations.c index 3441f55..70feea5 100644 --- a/get-contact-organisations.c +++ b/get-contact-organisations.c @@ -57,8 +57,10 @@ main(int argc, char *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 { - for (orgs = contact.organisations; (org = *orgs); orgs++) { + 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)) @@ -76,8 +78,8 @@ main(int argc, char *argv[]) else printf("%s\n", org->organisation); } - libcontacts_contact_destroy(&contact); } + libcontacts_contact_destroy(&contact); } if (fflush(stdout) || ferror(stdout) || fclose(stdout)) diff --git a/get-contact-pgpkeys.c b/get-contact-pgpkeys.c index ad56cc2..7935d17 100644 --- a/get-contact-pgpkeys.c +++ b/get-contact-pgpkeys.c @@ -57,8 +57,10 @@ main(int argc, char *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 { - for (keys = contact.pgpkeys; (key = *keys); keys++) { + 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)) @@ -76,8 +78,8 @@ main(int argc, char *argv[]) else printf("%s\n", key->context); } - libcontacts_contact_destroy(&contact); } + libcontacts_contact_destroy(&contact); } if (fflush(stdout) || ferror(stdout) || fclose(stdout)) diff --git a/get-contact-sites.c b/get-contact-sites.c index 7208d9f..06a8d6b 100644 --- a/get-contact-sites.c +++ b/get-contact-sites.c @@ -57,8 +57,10 @@ main(int argc, char *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 { - for (sites = contact.sites; (site = *sites); sites++) { + 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)) @@ -76,8 +78,8 @@ main(int argc, char *argv[]) else printf("%s\n", site->context); } - libcontacts_contact_destroy(&contact); } + libcontacts_contact_destroy(&contact); } if (fflush(stdout) || ferror(stdout) || fclose(stdout)) diff --git a/list-contact-groups.c b/list-contact-groups.c new file mode 100644 index 0000000..f0c1dd1 --- /dev/null +++ b/list-contact-groups.c @@ -0,0 +1,106 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("-L | contact-id ..."); + + +struct group_node { + char *name; + struct group_node *next; + struct group_node *prev; +}; + +static struct group_node head; +static struct group_node tail; + +static void +list_groups(const struct libcontacts_contact *contact) +{ + char **groups, *group; + struct group_node *node, *new; + int cmp; + + if ((groups = contact->groups)) { + for (; (group = *groups); groups++) { + for (node = head.next; node->next; node = node->next) { + cmp = strcmp(group, node->name); + if (cmp < 0) + continue; + if (cmp == 0) + goto next_group; + break; + } + printf("%s\n", group); + new = ecalloc(1, sizeof(*new)); + (new->prev = node->prev)->next = new; + (new->next = node)->prev = new; + new->name = estrdup(group); + next_group:; + } + } +} + +int +main(int argc, char *argv[]) +{ + int list = 0; + struct passwd *user; + struct libcontacts_contact **contacts, contact; + struct group_node *node, *next_node; + int ret = 0; + size_t i; + + ARGBEGIN { + case 'L': + list = 1; + break; + default: + usage(); + } ARGEND; + + if (list ? argc : !argc) + usage(); + + head.prev = NULL; + head.next = &tail; + tail.prev = &head; + tail.next = NULL; + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + if (list) { + if (libcontacts_load_contacts(&contacts, user)) + eprintf("libcontacts_load_contacts:"); + for (i = 0; contacts[i]; i++) { + list_groups(contacts[i]); + libcontacts_contact_destroy(contacts[i]); + free(contacts[i]); + } + free(contacts); + } else { + 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 { + list_groups(&contact); + libcontacts_contact_destroy(&contact); + } + } + } + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + + for (node = head.next; node->next; node = next_node) { + next_node = node->next; + free(node->name); + free(node); + } + + return ret; +} diff --git a/list-contact-organisations.c b/list-contact-organisations.c new file mode 100644 index 0000000..3a67e42 --- /dev/null +++ b/list-contact-organisations.c @@ -0,0 +1,117 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-t title] (-L | contact-id ...)"); + + +struct org_node { + char *name; + struct org_node *next; + struct org_node *prev; +}; + +static struct org_node head; +static struct org_node tail; + +static void +list_orgs(const struct libcontacts_contact *contact, const char *title) +{ + struct libcontacts_organisation **orgs, *org; + struct org_node *node, *new; + int cmp; + + if ((orgs = contact->organisations)) { + for (; (org = *orgs); orgs++) { + if (!org->organisation) + continue; + if (title && strcmpnul(org->title, title)) + continue; + for (node = head.next; node->next; node = node->next) { + cmp = strcmp(org->organisation, node->name); + if (cmp < 0) + continue; + if (cmp == 0) + goto next_org; + break; + } + printf("%s\n", org->organisation); + new = ecalloc(1, sizeof(*new)); + (new->prev = node->prev)->next = new; + (new->next = node)->prev = new; + new->name = org->organisation; + org->organisation = NULL; + next_org:; + } + } +} + +int +main(int argc, char *argv[]) +{ + int list = 0; + struct passwd *user; + struct libcontacts_contact **contacts, contact; + struct org_node *node, *next_node; + int ret = 0; + char *title = NULL; + size_t i; + + ARGBEGIN { + case 't': + if (title) + usage(); + title = ARG(); + break; + case 'L': + list = 1; + break; + default: + usage(); + } ARGEND; + + if (list ? argc : !argc) + usage(); + + head.prev = NULL; + head.next = &tail; + tail.prev = &head; + tail.next = NULL; + + errno = 0; + user = getpwuid(getuid()); + if (!user) + eprintf("getpwuid: %s\n", errno ? strerror(errno) : "user does not exist"); + + if (list) { + if (libcontacts_load_contacts(&contacts, user)) + eprintf("libcontacts_load_contacts:"); + for (i = 0; contacts[i]; i++) { + list_orgs(contacts[i], title); + libcontacts_contact_destroy(contacts[i]); + free(contacts[i]); + } + free(contacts); + } else { + 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 { + list_orgs(&contact, title); + libcontacts_contact_destroy(&contact); + } + } + } + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + + for (node = head.next; node->next; node = next_node) { + next_node = node->next; + free(node->name); + free(node); + } + + return ret; +} diff --git a/list-group-contacts.c b/list-group-contacts.c new file mode 100644 index 0000000..45299fd --- /dev/null +++ b/list-group-contacts.c @@ -0,0 +1,46 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("group ..."); + + +int +main(int argc, char *argv[]) +{ + struct passwd *user; + struct libcontacts_contact **contacts; + char **groups; + int ret = 0; + size_t i, j; + + NOFLAGS(!argc); + + 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 ((groups = contacts[i]->groups)) { + for (; *groups; groups++) { + for (j = 0; argv[j]; j++) { + if (!strcmp(*groups, argv[j])) { + printf("%s\n", contacts[i]->id); + goto done; + } + } + } + } + done: + libcontacts_contact_destroy(contacts[i]); + free(contacts[i]); + } + free(contacts); + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + + return ret; +} diff --git a/list-organisation-contacts.c b/list-organisation-contacts.c new file mode 100644 index 0000000..2e6ddae --- /dev/null +++ b/list-organisation-contacts.c @@ -0,0 +1,58 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-t title] organisation"); + + +int +main(int argc, char *argv[]) +{ + struct passwd *user; + struct libcontacts_contact **contacts; + struct libcontacts_organisation **orgs, *org; + char *title = NULL; + size_t i; + + ARGBEGIN { + case 't': + if (title) + usage(); + title = ARG(); + break; + default: + usage(); + } ARGEND; + + if (argc != 1) + 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 ((orgs = contacts[i]->organisations)) { + for (; (org = *orgs); orgs++) { + if (strcmpnul(org->organisation, argv[0])) + continue; + if (title && strcmpnul(org->title, title)) + continue; + if (title || !org->title) + printf("%s\n", contacts[i]->id); + else if (org->title) + printf("%s (%s)\n", contacts[i]->id, org->title); + } + } + libcontacts_contact_destroy(contacts[i]); + free(contacts[i]); + } + free(contacts); + + if (fflush(stdout) || ferror(stdout) || fclose(stdout)) + eprintf("printf:"); + + return 0; +} diff --git a/set-contact-gender.c b/set-contact-gender.c index f9750d6..b0b0258 100644 --- a/set-contact-gender.c +++ b/set-contact-gender.c @@ -57,14 +57,16 @@ main(int argc, char *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 { + continue; + } + if (contact.gender != gender) { contact.gender = gender; if (libcontacts_save_contact(&contact, user)) { weprintf("libcontacts_save_contact %s:", *argv); ret = 1; } - libcontacts_contact_destroy(&contact); } + libcontacts_contact_destroy(&contact); } return ret; diff --git a/set-contact-groups.c b/set-contact-groups.c new file mode 100644 index 0000000..2b8e3c1 --- /dev/null +++ b/set-contact-groups.c @@ -0,0 +1,79 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-u] contact-id ... group"); + + +int +main(int argc, char *argv[]) +{ + int remove = 0; + struct passwd *user; + struct libcontacts_contact contact; + char *group, **r, **w; + int ret = 0; + size_t i; + + ARGBEGIN { + case 'u': + remove = 1; + break; + default: + usage(); + } ARGEND; + + if (argc < 2) + usage(); + + group = argv[--argc]; + argv[argc] = NULL; + + 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 (contact.groups) { + for (i = 0; contact.groups[i]; i++) + if (!strcmp(contact.groups[i], group)) + break; + r = &contact.groups[i]; + if (remove && *r) { + free(*r); + for (w = r++; *r;) + *w++ = *r++; + *w = NULL; + 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; + add_group: + contact.groups = erealloc(contact.groups, (i + 2) * sizeof(*contact.groups)); + contact.groups[i + 1] = NULL; + contact.groups[i] = group; + if (libcontacts_save_contact(&contact, user)) { + weprintf("libcontacts_save_contact %s:", *argv); + ret = 1; + } + contact.groups[i] = NULL; + } + libcontacts_contact_destroy(&contact); + } + + return ret; +} |