/* See LICENSE file for copyright and license details. */ #include "common.h" static int parse(char *s, struct location *location) { errno = 0; location->latitude = strtod(s, &s); if (errno) return -1; while (isspace(*s)) s++; if (*s == ',' || *s == ':') s++; while (isspace(*s)) s++; location->longitude = strtod(s, &s); if (errno) return -1; while (isspace(*s) && *s != '\n') s++; return (*s && *s != '\n') ? -1 : 0; } int libgeome_get_from_file(struct libgeome_context *ctx, struct libgeome_data *out, const char *path) { struct location location; FILE *f; char *line = NULL; size_t size = 0; int r; if (!path) path = libgeome_default_geolocation_file; f = fopen(path, "r"); if (!f) { if (errno == ENOENT) ctx->print_debug(ctx, "fopen %s r: %s\n", path, strerror(errno)); else ctx->print_error(ctx, "fopen %s r: %s\n", path, strerror(errno)); return 1; } again: if (getline(&line, &size, f) < 0) { if (feof(f)) { ctx->print_debug(ctx, "%s is empty\n", path, strerror(errno)); } else { if (errno == EINTR) { clearerr(f); goto again; } ctx->print_error(ctx, "getline %s: %s\n", path, strerror(errno)); } fclose(f); free(line); return 1; } fclose(f); r = parse(line, &location); free(line); if (!r) { if (!isfinite(location.latitude) || !isfinite(location.longitude)) r = -1; else if (location.latitude < -90 || location.latitude > 90) r = -1; else if (location.longitude < -180 || location.longitude > 180) r = -1; } if (r) { ctx->print_debug(ctx, "the first line of %s was not a coordinate pair\n", path, strerror(errno)); return 1; } out->requested_data &= LIBGEOME_DATUM_LATITUDE | LIBGEOME_DATUM_LONGITUDE; if (out->requested_data) { if (out->requested_data & LIBGEOME_DATUM_LATITUDE) out->latitude = location.latitude; if (out->requested_data & LIBGEOME_DATUM_LONGITUDE) out->longitude = location.longitude; } return 0; }