diff options
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | README | 3 | ||||
| -rw-r--r-- | TODO | 1 | ||||
| -rw-r--r-- | libgeome.h | 124 | ||||
| -rw-r--r-- | libgeome_get_from_command.c | 4 | ||||
| -rw-r--r-- | libgeome_get_from_netservice.c | 12 | ||||
| -rw-r--r-- | libgeome_get_from_patterned_command.c | 164 | ||||
| -rw-r--r-- | libgeome_get_portability.c | 12 | 
8 files changed, 314 insertions, 11 deletions
| @@ -10,7 +10,7 @@ OS = linux  include mk/$(OS).mk -LIB_MAJOR = 1 +LIB_MAJOR = 2  LIB_MINOR = 0  LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR)  LIB_NAME = geome @@ -19,10 +19,13 @@ LIB_NAME = geome  OBJ =\  	libgeome_netservices.o\  	libgeome_basic_context.o\ +	libgeome_get_portability.o\  	libgeome_get_from_time.o\  	libgeome_get_from_timezone.o\  	libgeome_get_from_file.o\  	libgeome_get_from_command.o\ +	libgeome_get_from_patterned_command.o\ +	libgeome_get_from_netservice.o\  	util.o  HDR =\ @@ -37,6 +37,7 @@ SYNOPSIS  	       unsigned int alarm_seconds;  	       const char *path;  	       const char *const *args; +	       unsigned patterned : 1;  	};  	extern const struct libgeome_netservice libgeome_netservices[]; @@ -52,6 +53,8 @@ SYNOPSIS  	int libgeome_get_from_netservice(struct libgeome_context *, struct libgeome_data *,  	                                 const struct libgeome_netservice *); +	/* less fundament features omitted */ +  	Link with -lgeome -lm.  DESCRIPTION @@ -15,3 +15,4 @@ Add support for more automatic location determination  Add geome utility  Add support for detecting WiFi and cell towers, using a location service to get a location  Add support for detecting changes in nearby WiFi and cell towers +Make default file for libgeome_get_from_file visible to application @@ -25,6 +25,67 @@  /** + * Machine portability class + */ +enum libgeome_portability { +	/** +	 * No data available about the machine's +	 * portability class +	 */ +	LIBGEOME_UNKNOWN_PORTABILITY, + +	/** +	 * libgeome guesses that the machine is +	 * stationary (e.g. desktop computer) +	 */ +	LIBGEOME_GUESSED_STATIONARY, + +	/** +	 * libgeome guesses that the machine is +	 * movable but is usually not moving around +	 * while in use, or that these movement do +	 * not need to be closely tracked (e.g. +	 * laptop computer) +	 */ +	LIBGEOME_GUESSED_PORTABLE, + +	/** +	 * libgeome guesses that the machine is +	 * frequently on the move even when in use +	 * and that it may be desirable to keep +	 * the location updated with short intervals +	 * (e.g. mobile telephone) +	 */ +	LIBGEOME_GUESSED_MOBILE, + +	/** +	 * The user has specified that the machine +	 * is only being moved, a significant distance, +	 * in exceptional circumstances and only when +	 * powered off +	 */ +	LIBGEOME_STATIONARY, + +	/** +	 * The user has specified that the machine +	 * is at moved from time to time, regardless +	 * of whether it is powered on or off, but it +	 * is not usually useful to keep the location +	 * up to date with short intervals +	 */ +	LIBGEOME_PORTABLE, + +	/** +	 * The user hsa specified that the is often +	 * on the move when in use and that it is +	 * useful to keep the locations updated with +	 * short intervals +	 */ +	LIBGEOME_MOBILE +}; + + +/**   * Geolocation data   */  struct libgeome_data { @@ -158,6 +219,15 @@ struct libgeome_netservice {  	 * and an URL)  	 */  	const char *const *args; + +	/** +	 * Whether `.path` or `.args` contain %-patterns +	 * +	 * See `libgeome_get_from_patterned_command` for more information +	 *  +	 * @since  2.0 +	 */ +	unsigned patterned : 1;  }; @@ -198,6 +268,17 @@ extern const size_t libgeome_netservices_count;  void libgeome_basic_context(struct libgeome_context *ctx_out, const char *procname);  /** + * Get the machine's partability class + *  + * @param   ctx  Library context + * @param   out  Output parameter + * @return       0 on success, -1 on failure + *  + * @since  2.0 + */ +int libgeome_get_portability(struct libgeome_context *ctx, enum libgeome_portability *out); + +/**   * Get a very rough location guess based on   * the current timezone's offset from UTC   *  @@ -269,18 +350,49 @@ int libgeome_get_from_command(struct libgeome_context *ctx, struct libgeome_data   * Spawn a program and read it's standard output   * to get the user's location data   *  + * `path` and elements of `argv` are subject to %-substitution + * using the following rules: + *  + * -  The string is parsed from left to right + * -  Any '%' trigger substitutation + * -  If the next character is not '%', the "%%" is replaced with a literal "%" + * -  Otherwise the next character character must be '{' and '%' marks the beginning + *    of a %-pattern. + * -  Within a %-pattern "%%" is replaced with "%" and "%}" with "}", and no other + *    use of "%" is invalid (nested patterns are disallowed). + * -  A %-pattern ends with the first other occurance of a '}' + * -  Each %-pattern shall be on one of the two forms: + *    -  "%%{%u:%s}", <feature set>, <text> + *    -  "%%{!%u:%s}", <feature set>, <text> + *    The if the first pattern is used the pattern is deleted and only replaced with + *    <text> if `out->requested_data & <feature set>` is non-zero. + *    The if the second pattern is used the pattern is deleted and only replaced with + *    <text> if `out->requested_data & <feature set>` is zero. + *    <feature set> must be positive. + *  + * @param   ctx        Library context + * @param   out        Output parameter, `out->requested_data` must be set + * @param   limit      Number of bytes to stop reading output after, zero for default + * @param   alarm_sec  If non-zero, the number of seconds to let the subprocess live + * @param   path       Path to command to spawn + * @param   argv       Command line arguments for the process, including the name of the command + * @return             0 if data could be retrieved, even if none of the requested data + *                     could be retrieved, -1 otherwise + */ +int libgeome_get_from_patterned_command(struct libgeome_context *ctx, struct libgeome_data *out, size_t limit, +                                        unsigned int alarm_sec, const char *path, const char *const *argv); + +/** + * Spawn a program and read it's standard output + * to get the user's location data + *    * @param   ctx  Library context   * @param   out  Output parameter, `out->requested_data` must be set   * @param   svc  Parameters for the command to run   * @return       0 if data could be retrieved, even if none of the requested data   *               could be retrieved, -1 otherwise   */ -inline int -libgeome_get_from_netservice(struct libgeome_context *ctx, struct libgeome_data *out, -                             const struct libgeome_netservice *svc) -{ -	return libgeome_get_from_command(ctx, out, svc->limit, svc->alarm_seconds, svc->path, svc->args); -} +int libgeome_get_from_netservice(struct libgeome_context *ctx, struct libgeome_data *out, const struct libgeome_netservice *svc);  #endif diff --git a/libgeome_get_from_command.c b/libgeome_get_from_command.c index 8e224b6..9b5c338 100644 --- a/libgeome_get_from_command.c +++ b/libgeome_get_from_command.c @@ -94,7 +94,3 @@ libgeome_get_from_command(struct libgeome_context *ctx, struct libgeome_data *ou  	return 0;  } - - -extern inline int libgeome_get_from_netservice(struct libgeome_context *ctx, struct libgeome_data *out, -                                               const struct libgeome_netservice *svc); diff --git a/libgeome_get_from_netservice.c b/libgeome_get_from_netservice.c new file mode 100644 index 0000000..39abc87 --- /dev/null +++ b/libgeome_get_from_netservice.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +int +libgeome_get_from_netservice(struct libgeome_context *ctx, struct libgeome_data *out, const struct libgeome_netservice *svc) +{ +	if (svc->patterned) +		return libgeome_get_from_patterned_command(ctx, out, svc->limit, svc->alarm_seconds, svc->path, svc->args); +	else +		return libgeome_get_from_command(ctx, out, svc->limit, svc->alarm_seconds, svc->path, svc->args); +} diff --git a/libgeome_get_from_patterned_command.c b/libgeome_get_from_patterned_command.c new file mode 100644 index 0000000..7490dbb --- /dev/null +++ b/libgeome_get_from_patterned_command.c @@ -0,0 +1,164 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static char * +substitute(struct libgeome_context *ctx, const char *text, uint64_t features) +{ +	size_t len = 0, sublen; +	size_t i; +	int negative, include; +	uint64_t if_features, digit; +	char *ret, *p; + +	for (i = 0; text[i];) { +		if (text[i] != '%') { +			i += 1U; +			len += 1U; +		} else if (text[i + 1U] == '%') { +			i += 2U; +			len += 1U; +		} else if (text[i + 1U] == '{') { +			i += 2U; +			negative = text[i] == '!'; +			i += (size_t)negative; +			if_features = 0; +			for (; isdigit(text[i]); i++) { +				digit = (uint64_t)(text[i] & 15); +				if (if_features > (UINT64_MAX - digit) / 10U) +					goto invalid; +				if_features = if_features * 10U + digit; +			} +			if (!if_features || text[i++] != ':') +				goto invalid; +			include = !!(if_features & features); +			include ^= negative; +			sublen = 0; +			for (;;) { +				if (text[i] == '}') { +					i += 1U; +					break; +				} else if (!text[i]) { +					goto invalid; +				} else if (text[i] != '%') { +					i += 1U; +					sublen += 1U; +				} else if (text[i + 1U] == '%') { +					i += 1U; +					sublen += 2U; +				} else if (text[i + 1U] == '}') { +					i += 1U; +					sublen += 2U; +				} else { +					goto invalid; +				} +			} +			if (include ^ negative) +				len += sublen; +		} else { +		invalid: +			ctx->print_error(ctx, "invalid %-pattern in `%s'\n", text); +			return NULL; +		} +	} + +	p = ret = malloc(len + 1U); +	if (!ret) { +		ctx->print_error(ctx, "malloc: %s\n", strerror(errno)); +		return NULL; +	} + +	while (*text) { +		if (*text != '%') { +			*p++ = *text++; +		} else if (text[i + 1U] == '%') { +			text = &text[2]; +			*p++ = '%'; +		} else if (text[i + 1U] == '{') { +			text = &text[2]; +			negative = *text == '!'; +			text = &text[negative]; +			if_features = 0; +			while (isdigit(*text)) { +				digit = (uint64_t)(*text++ & 15); +				if_features = if_features * 10U + digit; +			} +			text++; +			include = !!(if_features & features); +			include ^= negative; +			for (; *text != '}'; text++) { +				if (include) +					*p++ = text[*text == '%']; +				if (*text == '%') +					text++; +			} +			text++; +		} +	} +	*p = '\0'; + +	return ret; +} + + +int +libgeome_get_from_patterned_command(struct libgeome_context *ctx, struct libgeome_data *out, size_t limit, /* TODO test */ +                                    unsigned int alarm_sec, const char *path, const char *const *argv) +{ +	const char **argv_new = NULL; +	char **array; +	size_t count = 0; +	size_t index = 0; +	size_t i, argc = 0; +	int ret = -1; + +	if (strchr(path, '%')) +		count += 1U; + +	for (i = 0; argv[i]; i++) +		if (strchr(argv[i], '%')) +			count += 1U; +	argc = i; + +	if (!count) +		return libgeome_get_from_patterned_command(ctx, out, limit, alarm_sec, path, argv); + +	array = calloc(count, sizeof(*array)); +	if (!array) { +		ctx->print_error(ctx, "calloc: %s\n", strerror(errno)); +		return -1; +	} + +	if (strchr(path, '%')) { +		path = array[index++] = substitute(ctx, path, out->requested_data); +		if (!path) +			goto out; +	} + +	if (index != count) { +		argv_new = calloc(argc + 1U, sizeof(*argv_new)); +		if (!argv_new) { +			ctx->print_error(ctx, "calloc: %s\n", strerror(errno)); +			goto out; +		} +		argv_new[argc] = NULL; +		for (i = 0; argv[i]; i++) { +			if (strchr(argv[i], '%')) { +				argv_new[i] = array[index++] = substitute(ctx, argv[i], out->requested_data); +				if (!argv_new[i]) +					goto out; +			} else { +				argv_new[i] = argv[i]; +			} +		} +		argv = argv_new; +	} + +	ret = libgeome_get_from_patterned_command(ctx, out, limit, alarm_sec, path, argv); +out: +	for (i = 0; i < count; i++) +		free(array[i]); +	free(array); +	free(argv_new); +	return ret; +} diff --git a/libgeome_get_portability.c b/libgeome_get_portability.c new file mode 100644 index 0000000..26b6477 --- /dev/null +++ b/libgeome_get_portability.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +int +libgeome_get_portability(struct libgeome_context *ctx, enum libgeome_portability *out) +{ +	/* TODO implement function */ +	(void) ctx; +	*out = LIBGEOME_UNKNOWN_PORTABILITY; +	return 0; +} | 
