1 /*
2     $Id: cddb_site.c,v 1.3 2005/06/15 16:12:04 airborne Exp $
3 
4     Copyright (C) 2005 Kris Verbeeck <airborne@advalvas.be>
5 
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public
8     License as published by the Free Software Foundation; either
9     version 2 of the License, or (at your option) any later version.
10 
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Library General Public License for more details.
15 
16     You should have received a copy of the GNU Library General Public
17     License along with this library; if not, write to the
18     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19     Boston, MA  02111-1307, USA.
20 */
21 
22 
23 #include "config.h"
24 
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 
29 #include "cddb/cddb_ni.h"
30 #include "cddb/cddb_site.h"
31 
32 
33 /* --- type and structure definitions */
34 
35 
36 struct cddb_site_s
37 {
38     char *address;              /**< host name of the CDDB server */
39     cddb_protocol_t protocol;   /**< the protocol used by this site */
40     int port;                   /**< port of the CDDB server */
41     char *query_path;           /**< query path for HTTP URL */
42     char *submit_path;          /**< submit path for HTTP URL */
43     char *desc;                 /**< server description */
44     float latitude;             /**< server latitude */
45     float longitude;            /**< server longitude */
46 };
47 
48 
49 /* --- private functions */
50 
51 
cddb_site_iconv(iconv_t cd,cddb_site_t * site)52 int cddb_site_iconv(iconv_t cd, cddb_site_t *site)
53 {
54     char *result;
55 
56     if (!cd) {
57         return TRUE;            /* no user character set defined */
58     }
59     if (site->desc) {
60         if (cddb_str_iconv(cd, site->desc, &result)) {
61             free(site->desc);
62             site->desc = result;
63         } else {
64             return FALSE;
65         }
66     }
67     return TRUE;
68 }
69 
70 
71 /* --- construction / destruction */
72 
73 
cddb_site_new(void)74 cddb_site_t *cddb_site_new(void)
75 {
76     cddb_site_t *site;
77 
78     site = (cddb_site_t*)calloc(1, sizeof(cddb_site_t));
79     return site;
80 }
81 
cddb_site_destroy(cddb_site_t * site)82 cddb_error_t cddb_site_destroy(cddb_site_t *site)
83 {
84     ASSERT_NOT_NULL(site);
85     FREE_NOT_NULL(site->address);
86     FREE_NOT_NULL(site->query_path);
87     FREE_NOT_NULL(site->submit_path);
88     FREE_NOT_NULL(site->desc);
89     free(site);
90     return CDDB_ERR_OK;
91 }
92 
cddb_site_clone(cddb_site_t * site)93 cddb_site_t *cddb_site_clone(cddb_site_t *site)
94 {
95     cddb_site_t *clone;
96 
97     cddb_log_debug("cddb_site_clone()");
98     clone = cddb_site_new();
99     clone->address = (site->address ? strdup(site->address) : NULL);
100     clone->protocol = site->protocol;
101     clone->port = site->port;
102     clone->query_path = (site->query_path ? strdup(site->query_path) : NULL);
103     clone->submit_path = (site->submit_path ? strdup(site->submit_path) : NULL);
104     clone->desc = (site->desc ? strdup(site->desc) : NULL);
105     clone->latitude = site->latitude;
106     clone->longitude = site->longitude;
107     return clone;
108 }
109 
110 
111 /* --- setters / getters --- */
112 
113 
cddb_site_get_address(const cddb_site_t * site,const char ** address,unsigned int * port)114 cddb_error_t cddb_site_get_address(const cddb_site_t *site,
115                                    const char **address, unsigned int *port)
116 {
117     ASSERT_NOT_NULL(site);
118     ASSERT_NOT_NULL(address);
119     ASSERT_NOT_NULL(port);
120     *address = site->address;
121     *port = site->port;
122     return CDDB_ERR_OK;
123 }
124 
cddb_site_set_address(cddb_site_t * site,const char * address,unsigned int port)125 cddb_error_t cddb_site_set_address(cddb_site_t *site,
126                                    const char *address, unsigned int port)
127 {
128     ASSERT_NOT_NULL(site);
129     ASSERT_NOT_NULL(address);
130     FREE_NOT_NULL(site->address);
131     site->address = strdup(address);
132     if (!site->address) {
133         return CDDB_ERR_OUT_OF_MEMORY;
134     }
135     site->port = port;
136     return CDDB_ERR_OK;
137 }
138 
cddb_site_get_location(const cddb_site_t * site,float * latitude,float * longitude)139 cddb_error_t cddb_site_get_location(const cddb_site_t *site,
140                                     float *latitude, float *longitude)
141 {
142     ASSERT_NOT_NULL(site);
143     ASSERT_NOT_NULL(latitude);
144     ASSERT_NOT_NULL(longitude);
145     *latitude = site->latitude;
146     *longitude = site->longitude;
147     return CDDB_ERR_OK;
148 }
149 
cddb_site_set_location(cddb_site_t * site,float latitude,float longitude)150 cddb_error_t cddb_site_set_location(cddb_site_t *site,
151                                     float latitude, float longitude)
152 {
153     ASSERT_NOT_NULL(site);
154     ASSERT_RANGE(latitude, -90.0, 90.0);
155     ASSERT_RANGE(longitude, -180.0, 180.0);
156     site->latitude = latitude;
157     site->longitude = longitude;
158     return CDDB_ERR_OK;
159 }
160 
cddb_site_get_protocol(const cddb_site_t * site)161 cddb_protocol_t cddb_site_get_protocol(const cddb_site_t *site)
162 {
163     if (site) {
164         return site->protocol;
165     }
166     return PROTO_UNKNOWN;
167 }
168 
cddb_site_set_protocol(cddb_site_t * site,cddb_protocol_t proto)169 cddb_error_t cddb_site_set_protocol(cddb_site_t *site, cddb_protocol_t proto)
170 {
171     ASSERT_NOT_NULL(site);
172     site->protocol = proto;
173     return CDDB_ERR_OK;
174 }
175 
cddb_site_get_query_path(const cddb_site_t * site,const char ** path)176 cddb_error_t cddb_site_get_query_path(const cddb_site_t *site,
177                                       const char **path)
178 {
179     ASSERT_NOT_NULL(site);
180     ASSERT_NOT_NULL(path);
181     *path = site->query_path;
182     return CDDB_ERR_OK;
183 }
184 
cddb_site_set_query_path(cddb_site_t * site,const char * path)185 cddb_error_t cddb_site_set_query_path(cddb_site_t *site, const char *path)
186 {
187     ASSERT_NOT_NULL(site);
188     FREE_NOT_NULL(site->query_path);
189     if (path) {
190         site->query_path = strdup(path);
191         if (!site->query_path) {
192             return CDDB_ERR_OUT_OF_MEMORY;
193         }
194     }
195     return CDDB_ERR_OK;
196 }
197 
cddb_site_get_submit_path(const cddb_site_t * site,const char ** path)198 cddb_error_t cddb_site_get_submit_path(const cddb_site_t *site,
199                                        const char **path)
200 {
201     ASSERT_NOT_NULL(site);
202     ASSERT_NOT_NULL(path);
203     *path = site->submit_path;
204     return CDDB_ERR_OK;
205 }
206 
cddb_site_set_submit_path(cddb_site_t * site,const char * path)207 cddb_error_t cddb_site_set_submit_path(cddb_site_t *site, const char *path)
208 {
209     ASSERT_NOT_NULL(site);
210     FREE_NOT_NULL(site->submit_path);
211     if (path) {
212         site->submit_path = strdup(path);
213         if (!site->submit_path) {
214             return CDDB_ERR_OUT_OF_MEMORY;
215         }
216     }
217     return CDDB_ERR_OK;
218 }
219 
cddb_site_get_description(const cddb_site_t * site,const char ** desc)220 cddb_error_t cddb_site_get_description(const cddb_site_t *site,
221                                        const char **desc)
222 {
223     ASSERT_NOT_NULL(site);
224     ASSERT_NOT_NULL(desc);
225     *desc = site->desc;
226     return CDDB_ERR_OK;
227 }
228 
cddb_site_set_description(cddb_site_t * site,const char * desc)229 cddb_error_t cddb_site_set_description(cddb_site_t *site, const char *desc)
230 {
231     ASSERT_NOT_NULL(site);
232     FREE_NOT_NULL(site->desc);
233     if (desc) {
234         site->desc = strdup(desc);
235         if (!site->desc) {
236             return CDDB_ERR_OUT_OF_MEMORY;
237         }
238     }
239     return CDDB_ERR_OK;
240 }
241 
242 
243 /* --- miscellaneous */
244 
245 
cddb_site_parse(cddb_site_t * site,const char * line)246 int cddb_site_parse(cddb_site_t *site, const char *line)
247 {
248     regmatch_t matches[10];
249     char *s;
250     float f;
251 
252     if (regexec(REGEX_SITE, line, 10, matches, 0) == REG_NOMATCH) {
253         /* invalid repsponse */
254         return FALSE;
255     }
256     site->address = cddb_regex_get_string(line, matches, 1);
257     s = cddb_regex_get_string(line, matches, 2);
258     if (strcmp(s, "cddbp") == 0) {
259         site->protocol = PROTO_CDDBP;
260     } else if (strcmp(s, "http") == 0) {
261         site->protocol = PROTO_HTTP;
262     } else {
263         site->protocol = PROTO_UNKNOWN;
264     }
265     site->port = cddb_regex_get_int(line, matches, 3);
266     site->query_path = cddb_regex_get_string(line, matches, 4);
267     s = cddb_regex_get_string(line, matches, 5);
268     f = cddb_regex_get_float(line, matches, 6);
269     if (*s == 'N') {
270         site->latitude = f;
271     } else if (*s == 'S') {
272         site->latitude = -f;
273     } else {
274         site->latitude = 0.0;
275     }
276     free(s);
277     s = cddb_regex_get_string(line, matches, 7);
278     f = cddb_regex_get_float(line, matches, 8);
279     if (*s == 'E') {
280         site->longitude = f;
281     } else if (*s == 'W') {
282         site->longitude = -f;
283     } else {
284         site->longitude = 0.0;
285     }
286     free(s);
287     site->desc = cddb_regex_get_string(line, matches, 9);
288     return TRUE;
289 }
290 
cddb_site_print(const cddb_site_t * site)291 cddb_error_t cddb_site_print(const cddb_site_t *site)
292 {
293     ASSERT_NOT_NULL(site);
294     printf("Address: ");
295     if (site->protocol == PROTO_CDDBP) {
296         printf("%s:%d\n", site->address, site->port);
297     } else if (site->protocol == PROTO_HTTP) {
298         printf("http://%s:%d%s\n", site->address, site->port, site->query_path);
299     }
300     printf("Description: %s\n", site->desc);
301     printf("Location: %4.2f %4.2f\n", site->latitude, site->longitude);
302     return CDDB_ERR_OK;
303 }
304