aboutsummaryrefslogtreecommitdiffstats
path: root/list-contact-organisations.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-04-03 12:55:33 +0200
committerMattias Andrée <maandree@kth.se>2021-04-03 12:55:33 +0200
commitc2b33333b84dd0534b2cb153c7a9f31c354ddad4 (patch)
tree21295fb55d63eeffefa43472f76c69de88979c9f /list-contact-organisations.c
parentm + Add multicall binary (diff)
downloadcontacts-c2b33333b84dd0534b2cb153c7a9f31c354ddad4.tar.gz
contacts-c2b33333b84dd0534b2cb153c7a9f31c354ddad4.tar.bz2
contacts-c2b33333b84dd0534b2cb153c7a9f31c354ddad4.tar.xz
m + add more tools
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--list-contact-organisations.c117
1 files changed, 117 insertions, 0 deletions
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;
+}