1 /* location-manual.c -- Manual location provider source
2 This file is part of Redshift.
3
4 Redshift is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 Redshift is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with Redshift. If not, see <http://www.gnu.org/licenses/>.
16
17 Copyright (c) 2010-2017 Jon Lund Steffensen <jonlst@gmail.com>
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <math.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #include "location-manual.h"
27
28 #ifdef ENABLE_NLS
29 # include <libintl.h>
30 # define _(s) gettext(s)
31 #else
32 # define _(s) s
33 #endif
34
35
36 typedef struct {
37 location_t loc;
38 } location_manual_state_t;
39
40
41 static int
location_manual_init(location_manual_state_t ** state)42 location_manual_init(location_manual_state_t **state)
43 {
44 *state = malloc(sizeof(location_manual_state_t));
45 if (*state == NULL) return -1;
46
47 location_manual_state_t *s = *state;
48 s->loc.lat = NAN;
49 s->loc.lon = NAN;
50
51 return 0;
52 }
53
54 static int
location_manual_start(location_manual_state_t * state)55 location_manual_start(location_manual_state_t *state)
56 {
57 /* Latitude and longitude must be set */
58 if (isnan(state->loc.lat) || isnan(state->loc.lon)) {
59 fputs(_("Latitude and longitude must be set.\n"), stderr);
60 exit(EXIT_FAILURE);
61 }
62
63 return 0;
64 }
65
66 static void
location_manual_free(location_manual_state_t * state)67 location_manual_free(location_manual_state_t *state)
68 {
69 free(state);
70 }
71
72 static void
location_manual_print_help(FILE * f)73 location_manual_print_help(FILE *f)
74 {
75 fputs(_("Specify location manually.\n"), f);
76 fputs("\n", f);
77
78 /* TRANSLATORS: Manual location help output
79 left column must not be translated */
80 fputs(_(" lat=N\t\tLatitude\n"
81 " lon=N\t\tLongitude\n"), f);
82 fputs("\n", f);
83 fputs(_("Both values are expected to be floating point numbers,\n"
84 "negative values representing west / south, respectively.\n"), f);
85 fputs("\n", f);
86 }
87
88 static int
location_manual_set_option(location_manual_state_t * state,const char * key,const char * value)89 location_manual_set_option(location_manual_state_t *state, const char *key,
90 const char *value)
91 {
92 /* Parse float value */
93 char *end;
94 errno = 0;
95 float v = strtof(value, &end);
96 if (errno != 0 || *end != '\0') {
97 fputs(_("Malformed argument.\n"), stderr);
98 return -1;
99 }
100
101 if (strcasecmp(key, "lat") == 0) {
102 state->loc.lat = v;
103 } else if (strcasecmp(key, "lon") == 0) {
104 state->loc.lon = v;
105 } else {
106 fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
107 return -1;
108 }
109
110 return 0;
111 }
112
113 static int
location_manual_get_fd(location_manual_state_t * state)114 location_manual_get_fd(location_manual_state_t *state)
115 {
116 return -1;
117 }
118
119 static int
location_manual_handle(location_manual_state_t * state,location_t * location,int * available)120 location_manual_handle(
121 location_manual_state_t *state, location_t *location, int *available)
122 {
123 *location = state->loc;
124 *available = 1;
125
126 return 0;
127 }
128
129
130 const location_provider_t manual_location_provider = {
131 "manual",
132 (location_provider_init_func *)location_manual_init,
133 (location_provider_start_func *)location_manual_start,
134 (location_provider_free_func *)location_manual_free,
135 (location_provider_print_help_func *)location_manual_print_help,
136 (location_provider_set_option_func *)location_manual_set_option,
137 (location_provider_get_fd_func *)location_manual_get_fd,
138 (location_provider_handle_func *)location_manual_handle
139 };
140