aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-04-03 19:26:35 +0200
committerMattias Andrée <maandree@kth.se>2021-04-03 19:26:35 +0200
commit2c6143d373c86f6b5c31e07d97447063766cd4eb (patch)
tree3f92f07cb737dad6f0f6f02bd191741fdd57edad
parentAdd photo utils (diff)
downloadcontacts-2c6143d373c86f6b5c31e07d97447063766cd4eb.tar.gz
contacts-2c6143d373c86f6b5c31e07d97447063766cd4eb.tar.bz2
contacts-2c6143d373c86f6b5c31e07d97447063766cd4eb.tar.xz
m + add chat utils
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--.gitignore4
-rw-r--r--Makefile16
-rw-r--r--TODO5
-rw-r--r--find-contact-by-chat.c76
-rw-r--r--get-contact-chats.c105
-rw-r--r--get-contact-emails.c16
-rw-r--r--get-contact-sites.c16
-rw-r--r--list-chat-contacts.c71
-rw-r--r--set-contact-chats.c112
9 files changed, 404 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 67e3b03..3ce8ba4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,12 +9,14 @@
*.bo
/contacts
/contacts.c
+/find-contact-by-chat
/find-contact-by-email
/find-contact-by-name
/find-contact-by-organisation
/find-contact-by-pgpkey
/find-contact-by-photo
/find-contact-by-site
+/get-contact-chats
/get-contact-emails
/get-contact-file
/get-contact-gender
@@ -26,11 +28,13 @@
/get-contact-photos
/get-contact-sites
/is-contact-ice
+/list-chat-contacts
/list-contact-groups
/list-contact-organisations
/list-contacts
/list-group-contacts
/list-organisation-contacts
+/set-contact-chats
/set-contact-emails
/set-contact-gender
/set-contact-groups
diff --git a/Makefile b/Makefile
index 347cb54..c821140 100644
--- a/Makefile
+++ b/Makefile
@@ -5,12 +5,14 @@ include $(CONFIGFILE)
BIN =\
+ find-contact-by-chat\
find-contact-by-email\
find-contact-by-name\
find-contact-by-organisation\
find-contact-by-pgpkey\
find-contact-by-photo\
find-contact-by-site\
+ get-contact-chats\
get-contact-emails\
get-contact-file\
get-contact-gender\
@@ -22,11 +24,13 @@ BIN =\
get-contact-photos\
get-contact-sites\
is-contact-ice\
+ list-chat-contacts\
list-contact-groups\
list-contact-organisations\
list-contacts\
list-group-contacts\
list-organisation-contacts\
+ set-contact-chats\
set-contact-emails\
set-contact-gender\
set-contact-groups\
@@ -64,6 +68,9 @@ contacts.c: contacts.c.in Makefile
printf '\n\n' >> $@
cat contacts.c.in >> $@
+find-contact-by-chat: find-contact-by-chat.o
+ $(CC) -o $@ $@.o $(LDFLAGS)
+
find-contact-by-email: find-contact-by-email.o
$(CC) -o $@ $@.o $(LDFLAGS)
@@ -82,6 +89,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-chats: get-contact-chats.o
+ $(CC) -o $@ $@.o $(LDFLAGS)
+
get-contact-emails: get-contact-emails.o
$(CC) -o $@ $@.o $(LDFLAGS)
@@ -115,6 +125,9 @@ get-contact-sites: get-contact-sites.o
is-contact-ice: is-contact-ice.o
$(CC) -o $@ $@.o $(LDFLAGS)
+list-chat-contacts: list-chat-contacts.o
+ $(CC) -o $@ $@.o $(LDFLAGS)
+
list-contact-groups: list-contact-groups.o
$(CC) -o $@ $@.o $(LDFLAGS)
@@ -130,6 +143,9 @@ list-group-contacts: list-group-contacts.o
list-organisation-contacts: list-organisation-contacts.o
$(CC) -o $@ $@.o $(LDFLAGS)
+set-contact-chats: set-contact-chats.o
+ $(CC) -o $@ $@.o $(LDFLAGS)
+
set-contact-emails: set-contact-emails.o
$(CC) -o $@ $@.o $(LDFLAGS)
diff --git a/TODO b/TODO
index 7fe8575..5ad9943 100644
--- a/TODO
+++ b/TODO
@@ -1,23 +1,26 @@
Add tools for .blocks
Add tools for .numbers
Add tools for .addresses
-Add tools for .chats
Add tools for .birthday
+Test find-contact-by-chat
Test find-contact-by-email
Test find-contact-by-name
Test find-contact-by-organisation
Test find-contact-by-pgpkey
Test find-contact-by-photo
Test find-contact-by-site
+Test get-contact-chats
Test get-contact-emails
Test get-contact-name
Test get-contact-organisations
Test get-contact-pgpkeys
Test get-contact-photos
Test get-contact-sites
+Test list-chat-contacts
Test list-contact-organisations
Test list-organisation-contacts
+Test set-contact-chats
Test set-contact-emails
Test set-contact-groups
Test set-contact-name
diff --git a/find-contact-by-chat.c b/find-contact-by-chat.c
new file mode 100644
index 0000000..282f847
--- /dev/null
+++ b/find-contact-by-chat.c
@@ -0,0 +1,76 @@
+/* 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;
+ 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;
+
+ 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 ((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;
+}
diff --git a/get-contact-chats.c b/get-contact-chats.c
new file mode 100644
index 0000000..4d25d66
--- /dev/null
+++ b/get-contact-chats.c
@@ -0,0 +1,105 @@
+/* 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;
+ struct passwd *user;
+ struct libcontacts_contact contact;
+ struct libcontacts_chat **chats, *chat;
+ const char *lookup_ctx = NULL, *lookup_addr = NULL, *lookup_srv = NULL;
+ 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;
+
+ if (!argc)
+ usage();
+
+ 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;
+}
diff --git a/get-contact-emails.c b/get-contact-emails.c
index c41b48f..257326e 100644
--- a/get-contact-emails.c
+++ b/get-contact-emails.c
@@ -1,7 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("[-c context] [-a address] [-CA] contact-id ...");
+USAGE("[-a address] [-c context] [-AC] contact-id ...");
int
@@ -16,22 +16,22 @@ main(int argc, char *argv[])
size_t i;
ARGBEGIN {
- case 'c':
- if (lookup_ctx)
- usage();
- lookup_ctx = ARG();
- break;
case 'a':
if (lookup_addr)
usage();
lookup_addr = ARG();
break;
- case 'C':
- display_ctx = 1;
+ 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;
diff --git a/get-contact-sites.c b/get-contact-sites.c
index 06a8d6b..dcc1d17 100644
--- a/get-contact-sites.c
+++ b/get-contact-sites.c
@@ -1,7 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("[-c context] [-a address] [-CA] contact-id ...");
+USAGE("[-a address] [-c context] [-AC] contact-id ...");
int
@@ -16,22 +16,22 @@ main(int argc, char *argv[])
size_t i;
ARGBEGIN {
- case 'c':
- if (lookup_ctx)
- usage();
- lookup_ctx = ARG();
- break;
case 'a':
if (lookup_addr)
usage();
lookup_addr = ARG();
break;
- case 'C':
- display_ctx = 1;
+ 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;
diff --git a/list-chat-contacts.c b/list-chat-contacts.c
new file mode 100644
index 0000000..eb262a9
--- /dev/null
+++ b/list-chat-contacts.c
@@ -0,0 +1,71 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("[-c context] [-a] service");
+
+
+int
+main(int argc, char *argv[])
+{
+ int display_address = 0;
+ struct passwd *user;
+ struct libcontacts_contact **contacts;
+ struct libcontacts_chat **chats, *chat;
+ char *context = NULL;
+ size_t i;
+
+ ARGBEGIN {
+ case 'a':
+ display_address = 1;
+ break;
+ case 'c':
+ if (context)
+ usage();
+ context = 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 ((chats = contacts[i]->chats)) {
+ for (; (chat = *chats); chats++) {
+ if (display_address && !chat->address)
+ continue;
+ if (strcmpnul(chat->service, argv[0]))
+ continue;
+ if (context && strcmpnul(chat->context, context))
+ continue;
+ if (context || !chat->context) {
+ if (display_address)
+ printf("%s (%s)\n", contacts[i]->id, chat->address);
+ else
+ printf("%s\n", contacts[i]->id);
+ } else if (chat->context) {
+ if (display_address)
+ printf("%s (%s: %s)\n", contacts[i]->id, chat->context, chat->address);
+ else
+ printf("%s (%s)\n", contacts[i]->id, chat->context);
+ }
+ }
+ }
+ 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-chats.c b/set-contact-chats.c
new file mode 100644
index 0000000..3d4bae9
--- /dev/null
+++ b/set-contact-chats.c
@@ -0,0 +1,112 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("[-a | -c | -s | -u] contact-id context service address");
+
+
+int
+main(int argc, char *argv[])
+{
+ int update_address = 0, update_context = 0, update_service = 0;
+ int remove = 0, edit;
+ struct passwd *user;
+ struct libcontacts_contact contact;
+ struct libcontacts_chat **r, **w;
+ size_t i;
+
+ ARGBEGIN {
+ case 'a':
+ update_address = 1;
+ break;
+ case 'c':
+ update_context = 1;
+ break;
+ case 's':
+ update_service = 1;
+ break;
+ case 'u':
+ remove = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ edit = update_address + update_context + update_service + remove;
+ if (edit > 1 || argc != 4)
+ 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.chats) {
+ if (!edit) {
+ for (; contact.chats[i]; i++);
+ } else if (update_address) {
+ for (; contact.chats[i]; i++) {
+ if (!strcmpnul(contact.chats[i]->context, argv[1])) {
+ if (!strcmpnul(contact.chats[i]->service, argv[2])) {
+ free(contact.chats[i]->address);
+ contact.chats[i]->address = estrdup(argv[3]);
+ goto save;
+ }
+ }
+ }
+ } else if (update_context) {
+ for (; contact.chats[i]; i++) {
+ if (!strcmpnul(contact.chats[i]->service, argv[2])) {
+ if (!strcmpnul(contact.chats[i]->address, argv[3])) {
+ free(contact.chats[i]->context);
+ contact.chats[i]->context = estrdup(argv[1]);
+ goto save;
+ }
+ }
+ }
+ } else if (update_service) {
+ for (; contact.chats[i]; i++) {
+ if (!strcmpnul(contact.chats[i]->context, argv[1])) {
+ if (!strcmpnul(contact.chats[i]->address, argv[3])) {
+ free(contact.chats[i]->context);
+ contact.chats[i]->service = estrdup(argv[2]);
+ goto save;
+ }
+ }
+ }
+ } else {
+ for (; contact.chats[i]; i++)
+ if (!strcmpnul(contact.chats[i]->context, argv[1]))
+ if (!strcmpnul(contact.chats[i]->service, argv[2]))
+ if (!strcmpnul(contact.chats[i]->address, argv[3]))
+ break;
+ }
+ }
+ if (!edit || update_address || update_context || update_service) {
+ 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 = estrdup(argv[1]);
+ contact.chats[i]->service = estrdup(argv[2]);
+ contact.chats[i]->address = estrdup(argv[3]);
+ } else if (contact.chats && contact.chats[i]) {
+ libcontacts_chat_destroy(contact.chats[i]);
+ free(contact.chats[i]);
+ for (r = &1[w = &contact.chats[i]]; *r;)
+ *w++ = *r++;
+ *w = NULL;
+ }
+
+save:
+ if (libcontacts_save_contact(&contact, user))
+ eprintf("libcontacts_save_contact %s:", argv[0]);
+ libcontacts_contact_destroy(&contact);
+
+ return 0;
+}