/* See LICENSE file for copyright and license details. */
#include "common.h"
USAGE("[-A old-ask-at] [-S old-service] [-T old-type] [-U old-unblock-at] [-Y old-style] "
"[-a new-ask-at] [-s new-service] [-t new-type] [-u new-unblock-at] [-y new-style] contact-id");
int
main(int argc, char *argv[])
{
int add = 1, edit = 0, explicit = 1, lookup_explicit = 1;
enum libcontacts_block_type shadow_block = LIBCONTACTS_BLOCK_IGNORE;
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;
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;
size_t i;
ARGBEGIN {
case 'A':
add = 0;
if (lookup_ask)
usage();
lookup_ask = ARG();
if (!isdigit(*lookup_ask))
usage();
lookup_soft_unblock = (time_t)strtoumax(lookup_ask, &p, 10);
if (errno || *p)
usage();
break;
case 'a':
edit = 1;
if (ask)
usage();
ask = ARG();
if (!isdigit(*ask))
usage();
soft_unblock = (time_t)strtoumax(ask, &p, 10);
if (errno || *p)
usage();
break;
case 'S':
add = 0;
if (lookup_srv)
usage();
lookup_srv = ARG();
break;
case 's':
edit = 1;
if (srv)
usage();
srv = ARG();
break;
case 'T':
add = 0;
if (lookup_type)
usage();
lookup_type = ARG();
break;
case 't':
edit = 1;
if (type)
usage();
type = ARG();
break;
case 'U':
add = 0;
if (lookup_ublk)
usage();
lookup_ublk = ARG();
if (!isdigit(*lookup_ublk))
usage();
lookup_hard_unblock = (time_t)strtoumax(lookup_ublk, &p, 10);
if (errno || *p)
usage();
break;
case 'u':
edit = 1;
if (ublk)
usage();
ublk = ARG();
if (!isdigit(*ublk))
usage();
hard_unblock = (time_t)strtoumax(ublk, &p, 10);
if (errno || *p)
usage();
break;
case 'Y':
add = 0;
if (lookup_style)
usage();
lookup_style = ARG();
break;
case 'y':
edit = 1;
if (style)
usage();
style = ARG();
break;
default:
usage();
} ARGEND;
if (argc != 1 || !*argv[0] || strchr(argv[0], '/'))
usage();
if (lookup_type) {
if (!strcmp(lookup_type, "explicit"))
lookup_explicit = 1;
else if (!strcmp(lookup_type, "shadow"))
lookup_explicit = 0;
else
eprintf("value of -T shall be either \"explicit\" or \"shadow\"\n");
}
if (type) {
if (!strcmp(type, "explicit"))
explicit = 1;
else if (!strcmp(type, "shadow"))
explicit = 0;
else
eprintf("value of -t shall be either \"explicit\" or \"shadow\"\n");
}
if (lookup_style) {
if (!strcmp(lookup_style, "silent"))
lookup_shadow_block = LIBCONTACTS_SILENT;
else if (!strcmp(lookup_style, "as-off"))
lookup_shadow_block = LIBCONTACTS_BLOCK_OFF;
else if (!strcmp(lookup_style, "as-busy"))
lookup_shadow_block = LIBCONTACTS_BLOCK_BUSY;
else if (!strcmp(lookup_style, "ignore"))
lookup_shadow_block = LIBCONTACTS_BLOCK_IGNORE;
else
eprintf("value of -Y shall be either \"silent\", \"as-off\", \"as-busy\", or \"ignore\"\n");
}
if (style) {
if (!strcmp(style, "silent"))
shadow_block = LIBCONTACTS_SILENT;
else if (!strcmp(style, "as-off"))
shadow_block = LIBCONTACTS_BLOCK_OFF;
else if (!strcmp(style, "as-busy"))
shadow_block = LIBCONTACTS_BLOCK_BUSY;
else if (!strcmp(style, "ignore"))
shadow_block = LIBCONTACTS_BLOCK_IGNORE;
else
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");
}
i = 0;
if (edit && contact.blocks) {
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)
continue;
if (lookup_style && contact.blocks[i]->shadow_block != lookup_shadow_block)
continue;
if (lookup_ask && contact.blocks[i]->soft_unblock != lookup_soft_unblock)
continue;
if (lookup_ublk && contact.blocks[i]->hard_unblock != lookup_hard_unblock)
continue;
if (srv) {
free(contact.blocks[i]->service);
contact.blocks[i]->service = estrdup(srv);
}
if (type)
contact.blocks[i]->explicit = explicit;
if (style)
contact.blocks[i]->shadow_block = shadow_block;
if (ask)
contact.blocks[i]->soft_unblock = soft_unblock;
if (ublk)
contact.blocks[i]->hard_unblock = hard_unblock;
}
} else if (!edit) {
if (contact.blocks)
for (; contact.blocks[i]; i++);
contact.blocks = erealloc(contact.blocks, (i + 2) * sizeof(*contact.blocks));
contact.blocks[i + 1] = NULL;
contact.blocks[i] = ecalloc(1, sizeof(**contact.blocks));
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;
contact.blocks[i]->hard_unblock = hard_unblock;
}
if (libcontacts_save_contact(&contact, user))
eprintf("libcontacts_save_contact %s:", argv[0]);
libcontacts_contact_destroy(&contact);
return 0;
}