aboutsummaryrefslogtreecommitdiffstats
path: root/libgeome.h
diff options
context:
space:
mode:
Diffstat (limited to 'libgeome.h')
-rw-r--r--libgeome.h273
1 files changed, 273 insertions, 0 deletions
diff --git a/libgeome.h b/libgeome.h
new file mode 100644
index 0000000..48e40e3
--- /dev/null
+++ b/libgeome.h
@@ -0,0 +1,273 @@
+/* See LICENSE file for copyright and license details. */
+#ifndef LIBGEOME_H
+#define LIBGEOME_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+
+#define LIBGEOME_DATUM_LATITUDE UINT64_C(0x0000000000000001)
+#define LIBGEOME_DATUM_LONGITUDE UINT64_C(0x0000000000000002)
+#define LIBGEOME_DATUM_ALTITUDE UINT64_C(0x0000000000000004)
+
+
+/**
+ * Geolocation data
+ */
+struct libgeome_data {
+ /**
+ * Requested data, data that was not retrieved will be cleared
+ */
+ uint64_t requested_data;
+
+ /**
+ * GPS latitude (geodetic) in degrees north
+ *
+ * Bit in `.requested_data`: LIBGEOME_DATUM_LATITUDE
+ */
+ double latitude;
+
+ /**
+ * GPS longitude (geodetic) in degrees east
+ *
+ * Bit in `.requested_data`: LIBGEOME_DATUM_LONGITUDE
+ */
+ double longitude;
+
+ /**
+ * Ellipsoidal altitude in meters
+ *
+ * Bit in `.requested_data`: LIBGEOME_DATUM_ALTITUDE
+ */
+ double altitude;
+};
+
+
+/**
+ * Library context
+ */
+struct libgeome_context {
+ /**
+ * The application is free to used this field as sees fit
+ */
+ union {
+ const void *cptr;
+ void *ptr;
+ int i;
+ unsigned int u;
+ size_t n;
+ } user_data;
+
+ /**
+ * Print error message
+ *
+ * @param ctx Function pointer container
+ * @param fmt Format string
+ * @param ... Format argument
+ */
+ void (*print_error)(struct libgeome_context *ctx, const char *fmt, ...);
+
+ /**
+ * Print error message for an error that the library
+ * cannot recover from. The library will abort the
+ * process after calling this function.
+ *
+ * @param ctx Function pointer container
+ * @param fmt Format string
+ * @param ... Format argument
+ */
+ void (*print_abort)(struct libgeome_context *ctx, const char *fmt, ...);
+
+ /**
+ * Print debug message
+ *
+ * @param ctx Function pointer container
+ * @param fmt Format string
+ * @param ... Format argument
+ */
+ void (*print_debug)(struct libgeome_context *ctx, const char *fmt, ...);
+};
+
+
+/**
+ * Geolocation network service description
+ */
+struct libgeome_netservice {
+ /**
+ * Geolocation data that may be provided by the service
+ *
+ * 0 if unknown (always known (non-zero) when retreived
+ * from libgeome_netservices)
+ *
+ * See `struct libgeome_data.requested_data`
+ */
+ uint64_t can_fetch;
+
+ /**
+ * A unique number assigned to each unique service,
+ * so that alternatives that user the same service
+ * can be recognised
+ *
+ * Only set when stated so in the source
+ *
+ * This is used because a service may have multiple
+ * ways to fetch the data, as all supported ones
+ * are added in case one is removed in the future;
+ * this could be multiple APIs or even multiple
+ * URLs
+ *
+ * These number are sorted and start from 0,
+ * and increment by one for each new service that's
+ * not just another way to use the service in the
+ * previous entry
+ */
+ size_t service_id;
+
+ /**
+ * Expected maximum output size
+ */
+ size_t limit;
+
+ /**
+ * Expected maximum invokation duration
+ */
+ unsigned int alarm_seconds;
+
+ /**
+ * Path command to run to get the location
+ * (this would be "curl")
+ */
+ const char *path;
+
+ /**
+ * Command to run to get the location
+ * (this would be curl with some parameters
+ * and an URL)
+ */
+ const char *const *args;
+};
+
+
+/**
+ * Built in list of geolocation network service
+ *
+ * `.service_id` is set
+ *
+ * Be aware these services may have terms of use that
+ * restrict how you are allowed to use them.
+ */
+extern struct libgeome_netservice libgeome_netservices[];
+
+/**
+ * The number of elements in `libgeome_netservices`
+ */
+extern const size_t libgeome_netservices_count;
+
+
+/**
+ * Create a basic initialisation for `struct libgeome_context`
+ *
+ * Note that the implementation will use `ctx_out->user_data` to store `procname`
+ * there. It will not make a copy of `procname`, so `procname` must be valid while
+ * the context is in use
+ *
+ * `*ctx_out->print_error` and `*ctx_out->print_abort` will print plain
+ * error messages, but `*ctx_out->print_debug` will not do anything.
+ * If you want debug outputs, you can assign `ctx_out->print_error` or
+ * `ctx_out->print_abort` to `ctx_out->print_debug`.
+ *
+ * @param ctx_out Structure to initialise
+ * @param procname The name of the process, will be prefixed to all outputs
+ * using the format `"%s: ", procname`. It may be a good idea
+ * to add prepend ": libgeome: " to make it clear that the
+ * output comes from libgeome
+ */
+void libgeome_basic_context(struct libgeome_context *ctx_out, const char *procname);
+
+/**
+ * Get a very rough location guess based on
+ * the current timezone's offset from UTC
+ *
+ * This can always be used to get the longitude,
+ * but only the longitude
+ *
+ * @param ctx Library context
+ * @param out Output parameter, `out->requested_data` must be set
+ * @return 0 if data could be retrieved, even if none of the requested data
+ * could be retrieved, -1 otherwise
+ */
+int libgeome_get_from_time(struct libgeome_context *ctx, struct libgeome_data *out);
+
+/**
+ * Get a rather rough location guess based on
+ * timezone data: the nominally the timezone's
+ * most populous city
+ *
+ * It is not guaranteed that the needed information
+ * is installed on the machine, and even if it is,
+ * does not necessarily contain needed data for the
+ * user's timezone
+ *
+ * This function will get both the latitude and
+ * the longitude but nothing more, provided it found
+ * data for the timezone
+ *
+ * @param ctx Library context
+ * @param out Output parameter, `out->requested_data` must be set
+ * @return 0 if data could be retrieved, even if none of the requested data
+ * could be retrieved, -1 otherwise
+ */
+int libgeome_get_from_timezone(struct libgeome_context *ctx, struct libgeome_data *out);
+
+/**
+ * Get the user's location from a file where it has
+ * been manually stored
+ *
+ * This function will get both the latitude and
+ * the longitude but nothing more
+ *
+ * The default file is /etc/geolocation unless changed at compile time
+ *
+ * @param ctx Library context
+ * @param out Output parameter, `out->requested_data` must be set
+ * @param path The file to read, `NULL` to use the default
+ * @return 0 if data could be retrieved, even if none of the requested data
+ * could be retrieved, -1 otherwise
+ */
+int libgeome_get_from_file(struct libgeome_context *ctx, struct libgeome_data *out, const char *path);
+
+/**
+ * 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 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_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);
+}
+
+
+#endif