diff options
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 14 | ||||
| -rw-r--r-- | TODO | 5 | ||||
| -rw-r--r-- | common-address.c | 6 | ||||
| -rw-r--r-- | common.h | 2 | ||||
| -rw-r--r-- | get-contact-blocks.c | 177 | ||||
| -rw-r--r-- | set-contact-blocks.c | 164 | ||||
| -rw-r--r-- | unblock-contact.c | 124 | 
8 files changed, 489 insertions, 6 deletions
| @@ -21,6 +21,7 @@  /find-contact-by-site  /get-contact-addresses  /get-contact-birthday +/get-contact-blocks  /get-contact-chats  /get-contact-emails  /get-contact-file @@ -45,6 +46,7 @@  /remove-contact  /set-contact-addresses  /set-contact-birthday +/set-contact-blocks  /set-contact-chats  /set-contact-emails  /set-contact-gender @@ -57,3 +59,4 @@  /set-contact-pgpkeys  /set-contact-photos  /set-contact-sites +/unblock-contact @@ -21,6 +21,7 @@ BIN =\  	find-contact-by-site\  	get-contact-addresses\  	get-contact-birthday\ +	get-contact-blocks\  	get-contact-chats\  	get-contact-emails\  	get-contact-file\ @@ -45,6 +46,7 @@ BIN =\  	remove-contact\  	set-contact-addresses\  	set-contact-birthday\ +	set-contact-blocks\  	set-contact-chats\  	set-contact-emails\  	set-contact-gender\ @@ -56,7 +58,8 @@ BIN =\  	set-contact-organisations\  	set-contact-pgpkeys\  	set-contact-photos\ -	set-contact-sites +	set-contact-sites\ +	unblock-contact  HDR =\  	common.h @@ -123,6 +126,9 @@ get-contact-addresses: get-contact-addresses.o common-address.o  get-contact-birthday: get-contact-birthday.o common-birthday.o  	$(CC) -o $@ $@.o common-birthday.o $(LDFLAGS) +get-contact-blocks: get-contact-blocks.o +	$(CC) -o $@ $@.o $(LDFLAGS) +  get-contact-chats: get-contact-chats.o  	$(CC) -o $@ $@.o $(LDFLAGS) @@ -195,6 +201,9 @@ set-contact-addresses: set-contact-addresses.o common-address.o  set-contact-birthday: set-contact-birthday.o  	$(CC) -o $@ $@.o $(LDFLAGS) +set-contact-blocks: set-contact-blocks.o +	$(CC) -o $@ $@.o $(LDFLAGS) +  set-contact-chats: set-contact-chats.o  	$(CC) -o $@ $@.o $(LDFLAGS) @@ -231,6 +240,9 @@ set-contact-photos: set-contact-photos.o  set-contact-sites: set-contact-sites.o  	$(CC) -o $@ $@.o $(LDFLAGS) +unblock-contact: unblock-contact.o +	$(CC) -o $@ $@.o $(LDFLAGS) +  uninstall:  	-cd -- "$(DESTDIR)$(PREFIX)/bin" && rm -f -- $(BIN)  	-rm -f -- "$(DESTDIR)$(PREFIX)/lib/contacts" @@ -1,4 +1,4 @@ -Add tools for .blocks +update list-contacts to handle block status  Test find-contact-by-chat  Test find-contact-by-email @@ -7,6 +7,7 @@ Test find-contact-by-organisation  Test find-contact-by-pgpkey  Test find-contact-by-photo  Test find-contact-by-site +Test get-contact-blocks  Test get-contact-chats  Test get-contact-emails  Test get-contact-numbers @@ -19,6 +20,7 @@ Test list-contact-organisations  Test list-organisation-contacts  Test set-contact-addresses  Test set-contact-birthday +Test set-contact-blocks  Test set-contact-chats  Test set-contact-emails  Test set-contact-groups @@ -28,6 +30,7 @@ Test set-contact-organisations  Test set-contact-pgpkeys  Test set-contact-photos  Test set-contact-sites +Test unblock-contact  Add ability to filter on unset values in entries  Add ability to remove values in entries  Add man pages diff --git a/common-address.c b/common-address.c index 2f66208..c8dbf7e 100644 --- a/common-address.c +++ b/common-address.c @@ -3,7 +3,7 @@  int -parse_coord(char *s, double *lat, double *lat_min, double *lat_max, double *lon, double *lon_min, double *lon_max) +parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, double *lon, double *lon_min, double *lon_max)  {          int withsign = 0, neg;  	long int tmp; @@ -22,7 +22,7 @@ parse_coord(char *s, double *lat, double *lat_min, double *lat_max, double *lon,  		s = &s[withsign];  		tmp = 0;  		if (isdigit(s[withsign])) { -			tmp = strtol(s, &s, 0); +			tmp = strtol(s, (void *)&s, 0);  			if (errno || tmp > INT_MAX)  				return -1;  		} @@ -61,7 +61,7 @@ parse_coord(char *s, double *lat, double *lat_min, double *lat_max, double *lon,  		s = &s[withsign];  		tmp = 0;  		if (isdigit(s[withsign])) { -			tmp = strtol(s, &s, 0); +			tmp = strtol(s, (void *)&s, 0);  			if (errno || tmp > INT_MAX)  				return -1;  		} @@ -24,4 +24,4 @@ void print_birthdate(struct libcontacts_birthday *bday, const struct tm *now);  void print_birthday(struct libcontacts_birthday *bday, const struct tm *now);  /* common-address.c */ -int parse_coord(char *s, double *lat, double *lat_min, double *lat_max, double *lon, double *lon_min, double *lon_max); +int parse_coord(const char *s, double *lat, double *lat_min, double *lat_max, double *lon, double *lon_min, double *lon_max); diff --git a/get-contact-blocks.c b/get-contact-blocks.c new file mode 100644 index 0000000..63dc713 --- /dev/null +++ b/get-contact-blocks.c @@ -0,0 +1,177 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-a ask-at] [-s service] [-t type] [-u unblock-at] [-y style] [-ASTUY] contact-id ..."); + + +int +main(int argc, char *argv[]) +{ +	int display_srv = 0, display_type = 0, display_style = 0; +	int display_ask = 0, display_ublk = 0, explicit = 0; +	enum libcontacts_block_type style = 0; +	time_t soft_unblock = 0, hard_unblock = 0; +	const char *lookup_srv = NULL, *lookup_type = NULL, *lookup_style = NULL; +	const char *lookup_ask = NULL, *lookup_ublk = NULL; +	char *p; +	struct passwd *user; +	struct libcontacts_contact contact; +	struct libcontacts_block **blocks, *block; +	int ret = 0; +	size_t i; + +	errno = 0; + +	ARGBEGIN { +	case 's': +		if (lookup_srv) +			usage(); +		lookup_srv = ARG(); +		break; +	case 't': +		if (lookup_type) +			usage(); +		lookup_type = ARG(); +		break; +	case 'y': +		if (lookup_style) +			usage(); +		lookup_style = ARG(); +		break; +	case 'a': +		if (lookup_ask) +			usage(); +		lookup_ask = ARG(); +		if (!isdigit(*lookup_ask)) +			usage(); +		soft_unblock = (time_t)strtoumax(lookup_ask, &p, 10); +		if (errno || *p) +			usage(); +		break; +	case 'u': +		if (lookup_ublk) +			usage(); +		lookup_ublk = ARG(); +		if (!isdigit(*lookup_ublk)) +			usage(); +		hard_unblock = (time_t)strtoumax(lookup_ublk, &p, 10); +		if (errno || *p) +			usage(); +		break; +	case 'S': +		display_srv = 1; +		break; +	case 'T': +		display_type = 1; +		break; +	case 'Y': +		display_style = 1; +		break; +	case 'A': +		display_ask = 1; +		break; +	case 'U': +		display_ublk = 1; +		break; +	default: +		usage(); +	} ARGEND; + +	if (!argc) +		usage(); + +	for (i = 0; argv[i]; i++) +		if (!*argv[i] || strchr(argv[i], '/')) +			usage(); + +	if (lookup_type) { +		if (!strcmp(lookup_type, "explicit")) +			explicit = 1; +		else if (!strcmp(lookup_type, "shadow")) +			explicit = 0; +		else +			eprintf("value of -t shall be either \"explicit\" or \"shadow\"\n"); +	} + +	if (lookup_style) { +		if (!strcmp(lookup_style, "silent")) +			style = LIBCONTACTS_SILENT; +		else if (!strcmp(lookup_style, "as-off")) +			style = LIBCONTACTS_BLOCK_OFF; +		else if (!strcmp(lookup_style, "as-busy")) +			style = LIBCONTACTS_BLOCK_BUSY; +		else if (!strcmp(lookup_style, "ignore")) +			style = LIBCONTACTS_BLOCK_IGNORE; +		else +			eprintf("value of -y shall be either \"silent\", \"as-off\", \"as-busy\", or \"ignore\"\n"); +	} + +	if (!display_srv && !display_type && !display_style && !display_ask && !display_ublk) { +		display_srv   = !lookup_srv; +		display_type  = !lookup_type; +		display_style = !lookup_style; +		display_ask   = !lookup_ask; +		display_ublk  = !lookup_ublk; +		if (!display_srv && !display_type && !display_style && !display_ask && !display_ublk) +			display_srv = display_type = display_style = display_ask = display_ublk = 1; +	} + +	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 ((blocks = contact.blocks)) { +			for (; (block = *blocks); blocks++) { +				if (lookup_srv && strcmpnul(block->service, lookup_srv)) +					continue; +				if (lookup_type && block->explicit != explicit) +					continue; +				if (lookup_style && block->shadow_block != style) +					continue; +				if (lookup_ask && block->soft_unblock != soft_unblock) +					continue; +				if (lookup_ublk && block->hard_unblock != hard_unblock) +					continue; +				if (argc > 1) +					printf("%s: ", *argv); +				if (display_srv) { +					printf("%s%s", block->service, display_type + display_style + +					               display_ask + display_ublk ? "; " : "\n"); +				} +				if (display_type) { +					printf("%s%s", block->explicit ? "explicit" : "shadow", +					               display_style + display_ask + display_ublk ? "; " : "\n"); +				} +				if (display_style) { +					if (block->shadow_block == LIBCONTACTS_SILENT) +						printf("silent"); +					else if (block->shadow_block == LIBCONTACTS_BLOCK_OFF) +						printf("as-off"); +					else if (block->shadow_block == LIBCONTACTS_BLOCK_BUSY) +						printf("as-busy"); +					else if (block->shadow_block == LIBCONTACTS_BLOCK_IGNORE) +						printf("ignore"); +					else +						printf("???"); +					printf("%s", display_ask + display_ublk ? "; " : "\n"); +				} +				if (display_ask) +					printf("%ju%s", (uintmax_t)block->soft_unblock, display_ublk ? "; " : "\n"); +				if (display_ublk) +					printf("%ju\n", (uintmax_t)block->hard_unblock); +			} +		} +		libcontacts_contact_destroy(&contact); +	} + +	if (fflush(stdout) || ferror(stdout) || fclose(stdout)) +		eprintf("printf:"); +	return ret; +} diff --git a/set-contact-blocks.c b/set-contact-blocks.c new file mode 100644 index 0000000..31e6626 --- /dev/null +++ b/set-contact-blocks.c @@ -0,0 +1,164 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-a ask-at | -A ask-at] [-s service | -S service] [-t type | -T type] " +      "[-u unblock-at | -U unblock-at] [-y style | -Y style] contact-id"); + + +int +main(int argc, char *argv[]) +{ +	int edit_srv = 0, edit_type = 0, edit_style = 0, edit_ask = 0, edit_ublk = 0; +	int edit = 0, explicit = 1; +	enum libcontacts_block_type shadow_block = LIBCONTACTS_BLOCK_IGNORE; +	time_t soft_unblock = 0, hard_unblock = 0; +	const char *srv = NULL, *type = NULL, *style = NULL, *ask = NULL, *ublk = NULL; +	struct passwd *user; +	struct libcontacts_contact contact; +	char *p; +	size_t i; + +	ARGBEGIN { +	case 'A': +		edit_ask = 1; +		edit = 1; +		/* fall through */ +	case 'a': +		if (ask) +			usage(); +		ask = ARG(); +		if (!isdigit(*ask)) +			usage(); +		soft_unblock = (time_t)strtoumax(ask, &p, 10); +		if (errno || *p) +			usage(); +		break; +	case 'S': +		edit_srv = 1; +		edit = 1; +		/* fall through */ +	case 's': +		if (srv) +			usage(); +		srv = ARG(); +		break; +	case 'T': +		edit_type = 1; +		edit = 1; +		/* fall through */ +	case 't': +		if (type) +			usage(); +		type = ARG(); +		break; +	case 'U': +		edit_ublk = 1; +		edit = 1; +		/* fall through */ +	case 'u': +		if (ublk) +			usage(); +		ublk = ARG(); +		if (!isdigit(*ublk)) +			usage(); +		hard_unblock = (time_t)strtoumax(ublk, &p, 10); +		if (errno || *p) +			usage(); +		break; +	case 'Y': +		edit_style = 1; +		edit = 1; +		/* fall through */ +	case 'y': +		if (style) +			usage(); +		style = ARG(); +		break; +	default: +		usage(); +	} ARGEND; + +	if ((!srv || edit_srv) && (!type || edit_type) && (!style || edit_style) && +	    (!ask || edit_ask) && (!ublk || edit_ublk)) +		edit = 0; + +	if (argc != 1 || !*argv[0] || strchr(argv[0], '/')) +		usage(); + +	if (type) { +		if (!strcmp(type, "explicit")) +			explicit = 1; +		else if (!strcmp(type, "shadow")) +			explicit = 0; +		else +			eprintf("value of -%c shall be either \"explicit\" or \"shadow\"\n", edit_type ? 'T' : 't'); +	} + +	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 if (edit_style) +			eprintf("value of -Y shall be either \"silent\", \"as-off\", \"as-busy\", or \"ignore\"\n"); +		else +			eprintf("value of -y shall be either \"silent\", \"as-off\", \"as-busy\", or \"ignore\"\n"); +	} + +	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"); + +	if (edit && contact.blocks) { +		for (i = 0; contact.blocks[i]; i++) { +			if (srv && !edit_srv && strcmpnul(contact.blocks[i]->service, srv)) +				continue; +			if (type && !edit_type && contact.blocks[i]->explicit != explicit) +				continue; +			if (style && !edit_style && contact.blocks[i]->shadow_block != shadow_block) +				continue; +			if (ask && !edit_ask && contact.blocks[i]->soft_unblock != soft_unblock) +				continue; +			if (ublk && !edit_ublk && contact.blocks[i]->hard_unblock != hard_unblock) +				continue; +			if (edit_srv) { +				free(contact.blocks[i]->service); +				contact.blocks[i]->service = estrdup(srv); +			} +			if (edit_type) +				contact.blocks[i]->explicit = explicit; +			if (edit_style) +				contact.blocks[i]->shadow_block = shadow_block; +			if (edit_ask) +				contact.blocks[i]->soft_unblock = soft_unblock; +			if (edit_ublk) +				contact.blocks[i]->hard_unblock = hard_unblock; +		} +	} else if (!edit) { +		i = 0; +		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.emails)); +		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; +} diff --git a/unblock-contact.c b/unblock-contact.c new file mode 100644 index 0000000..ad2b5a0 --- /dev/null +++ b/unblock-contact.c @@ -0,0 +1,124 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-a ask-at] [-s service] [-t type] [-u unblock-at] [-y style] contact-id ..."); + + +int +main(int argc, char *argv[]) +{ +	int explicit = 0; +	enum libcontacts_block_type shadow_block = 0; +	time_t soft_unblock = 0, hard_unblock = 0; +	const char *srv = NULL, *type = NULL, *style = NULL, *ask = NULL, *ublk = NULL; +	struct passwd *user; +	struct libcontacts_contact contact; +	struct libcontacts_block **r, **w; +	char *p; +	size_t i; +	int ret = 0; + +	ARGBEGIN { +	case 'a': +		if (ask) +			usage(); +		ask = ARG(); +		if (!isdigit(*ask)) +			usage(); +		soft_unblock = (time_t)strtoumax(ask, &p, 10); +		if (errno || *p) +			usage(); +		break; +	case 's': +		if (srv) +			usage(); +		srv = ARG(); +		break; +	case 't': +		if (type) +			usage(); +		type = ARG(); +		break; +	case 'u': +		if (ublk) +			usage(); +		ublk = ARG(); +		if (!isdigit(*ublk)) +			usage(); +		hard_unblock = (time_t)strtoumax(ublk, &p, 10); +		if (errno || *p) +			usage(); +		break; +	case 'y': +		if (style) +			usage(); +		style = ARG(); +		break; +	default: +		usage(); +	} ARGEND; + +	if (!argc) +		usage(); + +	for (i = 0; argv[i]; i++) +		if (!*argv[i] || strchr(argv[i], '/')) +			usage(); + +	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 (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"); +	} + +	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 ((r = contact.blocks)) { +			for (w = r; *r; w++) { +				*w = *r++; +				if (srv && strcmpnul((*w)->service, srv)) +					continue; +				if (type && (*w)->explicit != explicit) +					continue; +				if (style && (*w)->shadow_block != shadow_block) +					continue; +				if (ask && (*w)->soft_unblock != soft_unblock) +					continue; +				if (ublk && (*w)->hard_unblock != hard_unblock) +					continue; +				libcontacts_block_destroy(*w); +				free(*w--); +			} +			if (libcontacts_save_contact(&contact, user)) +				eprintf("libcontacts_save_contact %s:", *argv); +		} +		libcontacts_contact_destroy(&contact); +	} + +	return ret; +} | 
