1 /*
2 $Id: cddb_conn.c,v 1.39 2006/10/15 11:53:11 airborne Exp $
3
4 Copyright (C) 2003, 2004, 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 #include "cddb/cddb_ni.h"
23
24 #ifdef HAVE_SYS_TYPES_H
25 #include <sys/types.h>
26 #endif
27
28 #ifdef HAVE_NETDB_H
29 #include <netdb.h>
30 #endif
31
32 #ifdef HAVE_ARPA_INET_H
33 #include <arpa/inet.h>
34 #endif
35
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39
40 #ifdef HAVE_STRING_H
41 #include <string.h>
42 #endif
43
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif
47
48
49 /* --- prototypes --- */
50
51
52 /**
53 * Send handshake to CDDB server.
54 */
55 static int cddb_handshake(cddb_conn_t *c);
56
57 /**
58 * Reset proxy authentication credentials.
59 */
60 static void cddb_set_http_proxy_auth(cddb_conn_t *c,
61 const char *username,
62 const char *password);
63
64
65 /* --- construction / destruction --- */
66
67
cddb_new(void)68 cddb_conn_t *cddb_new(void)
69 {
70 cddb_conn_t *c;
71 const char *s;
72
73 libcddb_init(); /* initialize globals if not yet done */
74 c = (cddb_conn_t*)malloc(sizeof(cddb_conn_t));
75 if (c) {
76 c->buf_size = DEFAULT_BUF_SIZE;
77 c->line = (char*)malloc(c->buf_size);
78
79 c->cname = strdup(CLIENT_NAME);
80 c->cversion = strdup(CLIENT_VERSION);
81
82 c->is_connected = FALSE;
83 c->socket = -1;
84 c->cache_fp = NULL;
85 c->server_name = strdup(DEFAULT_SERVER);
86 c->server_port = DEFAULT_PORT;
87 c->timeout = DEFAULT_TIMEOUT;
88
89 c->http_path_query = strdup(DEFAULT_PATH_QUERY);
90 c->http_path_submit = strdup(DEFAULT_PATH_SUBMIT);
91
92 c->is_http_enabled = FALSE;
93 c->is_http_proxy_enabled = FALSE;
94 c->http_proxy_server = NULL;
95 c->http_proxy_server_port = DEFAULT_PROXY_PORT;
96 c->http_proxy_username = NULL;
97 c->http_proxy_password = NULL;
98 c->http_proxy_auth = NULL;
99
100 c->use_cache = CACHE_ON;
101 /* construct cache dir '$HOME/[DEFAULT_CACHE]' */
102 s = getenv("HOME");
103 c->cache_dir = (char*)malloc(strlen(s) + 1 + sizeof(DEFAULT_CACHE) + 1);
104 sprintf(c->cache_dir, "%s/%s", s, DEFAULT_CACHE);
105 c->cache_read = FALSE;
106
107 /* use anonymous@localhost */
108 c->user = strdup(DEFAULT_USER);
109 c->hostname = strdup(DEFAULT_HOST);
110
111 c->errnum = CDDB_ERR_OK;
112
113 // XXX: handle out-of-memory
114 c->query_data = list_new((elem_destroy_cb*)cddb_disc_destroy);
115 c->sites_data = list_new((elem_destroy_cb*)cddb_site_destroy);
116
117 c->charset = malloc(sizeof(struct cddb_iconv_s));
118 c->charset->cd_to_freedb = NULL;
119 c->charset->cd_from_freedb = NULL;
120
121 c->srch.fields = SEARCH_ARTIST | SEARCH_TITLE;
122 c->srch.cats = SEARCH_ALL;
123 } else {
124 cddb_log_crit(cddb_error_str(CDDB_ERR_OUT_OF_MEMORY));
125 }
126
127 return c;
128 }
129
cddb_close_iconv(cddb_conn_t * c)130 static void cddb_close_iconv(cddb_conn_t *c)
131 {
132 if (c->charset) {
133 #ifdef HAVE_ICONV_H
134 if (c->charset->cd_to_freedb) {
135 iconv_close(c->charset->cd_to_freedb);
136 }
137 if (c->charset->cd_from_freedb) {
138 iconv_close(c->charset->cd_from_freedb);
139 }
140 #endif /* HAVE_ICONV_H */
141 }
142 }
143
cddb_destroy(cddb_conn_t * c)144 void cddb_destroy(cddb_conn_t *c)
145 {
146 if (c) {
147 cddb_disconnect(c);
148 FREE_NOT_NULL(c->line);
149 FREE_NOT_NULL(c->cname);
150 FREE_NOT_NULL(c->cversion);
151 FREE_NOT_NULL(c->server_name);
152 FREE_NOT_NULL(c->http_path_query);
153 FREE_NOT_NULL(c->http_path_submit);
154 FREE_NOT_NULL(c->http_proxy_server);
155 FREE_NOT_NULL(c->http_proxy_username);
156 FREE_NOT_NULL(c->http_proxy_password);
157 FREE_NOT_NULL(c->cache_dir);
158 FREE_NOT_NULL(c->user);
159 FREE_NOT_NULL(c->hostname);
160 list_destroy(c->query_data);
161 list_destroy(c->sites_data);
162 cddb_close_iconv(c);
163 FREE_NOT_NULL(c->charset);
164 free(c);
165 }
166 }
167
168
169 /* --- getters & setters --- */
170
171
cddb_set_charset(cddb_conn_t * c,const char * charset)172 int cddb_set_charset(cddb_conn_t *c, const char *charset)
173 {
174 #ifdef HAVE_ICONV_H
175 cddb_close_iconv(c);
176 c->charset->cd_to_freedb = iconv_open(SERVER_CHARSET, charset);
177 if (c->charset->cd_to_freedb == (iconv_t)-1) {
178 c->charset->cd_to_freedb = NULL;
179 cddb_errno_set(c, CDDB_ERR_INVALID_CHARSET);
180 return FALSE;
181 }
182 c->charset->cd_from_freedb = iconv_open(charset, SERVER_CHARSET);
183 if (c->charset->cd_from_freedb == (iconv_t)-1) {
184 iconv_close(c->charset->cd_to_freedb);
185 c->charset->cd_to_freedb = NULL;
186 c->charset->cd_from_freedb = NULL;
187 cddb_errno_set(c, CDDB_ERR_INVALID_CHARSET);
188 return FALSE;
189 }
190 cddb_errno_set(c, CDDB_ERR_OK);
191 return TRUE;
192 #else
193 cddb_errno_set(c, CDDB_ERR_ICONV_FAIL);
194 return FALSE;
195 #endif /* HAVE_ICONV_H */
196 }
197
cddb_set_buf_size(cddb_conn_t * c,unsigned int size)198 void cddb_set_buf_size(cddb_conn_t *c, unsigned int size)
199 {
200 FREE_NOT_NULL(c->line);
201 c->buf_size = size;
202 c->line = (char*)malloc(c->buf_size);
203 }
204
cddb_set_site(cddb_conn_t * c,const cddb_site_t * site)205 cddb_error_t cddb_set_site(cddb_conn_t *c, const cddb_site_t *site)
206 {
207 cddb_error_t rv;
208 const char *server, *path;
209 unsigned int port;
210 cddb_protocol_t proto;
211
212 ASSERT_NOT_NULL(c);
213 if ((rv = cddb_site_get_address(site, &server, &port)) != CDDB_ERR_OK) {
214 cddb_errno_set(c, rv);
215 return rv;
216 }
217 if ((proto = cddb_site_get_protocol(site)) == PROTO_UNKNOWN) {
218 cddb_errno_set(c, CDDB_ERR_INVALID);
219 return CDDB_ERR_INVALID;
220 }
221 if ((rv = cddb_site_get_query_path(site, &path)) != CDDB_ERR_OK) {
222 cddb_errno_set(c, rv);
223 return rv;
224 }
225 cddb_set_server_name(c, server);
226 cddb_set_server_port(c, port);
227 if (proto == PROTO_CDDBP) {
228 cddb_http_disable(c);
229 } else {
230 cddb_http_enable(c);
231 cddb_set_http_path_query(c, path);
232 }
233 return cddb_errno_set(c, CDDB_ERR_OK);
234 }
235
cddb_get_server_name(const cddb_conn_t * c)236 const char *cddb_get_server_name(const cddb_conn_t *c)
237 {
238 const char *server = NULL;
239
240 if (c) {
241 server = c->server_name;
242 }
243 RETURN_STR_OR_EMPTY(server);
244 }
245
cddb_set_server_name(cddb_conn_t * c,const char * server)246 void cddb_set_server_name(cddb_conn_t *c, const char *server)
247 {
248 FREE_NOT_NULL(c->server_name);
249 c->server_name = strdup(server);
250 }
251
cddb_get_server_port(const cddb_conn_t * c)252 unsigned int cddb_get_server_port(const cddb_conn_t *c)
253 {
254 if (c) {
255 return c->server_port;
256 }
257 return 0;
258 }
259
cddb_set_server_port(cddb_conn_t * c,int port)260 void cddb_set_server_port(cddb_conn_t *c, int port)
261 {
262 c->server_port = port;
263 }
264
cddb_get_timeout(const cddb_conn_t * c)265 unsigned int cddb_get_timeout(const cddb_conn_t *c)
266 {
267 if (c) {
268 return c->timeout;
269 }
270 return 0;
271 }
272
cddb_set_timeout(cddb_conn_t * c,unsigned int t)273 void cddb_set_timeout(cddb_conn_t *c, unsigned int t)
274 {
275 if (c) {
276 c->timeout = t;
277 }
278 }
279
cddb_get_http_path_query(const cddb_conn_t * c)280 const char *cddb_get_http_path_query(const cddb_conn_t *c)
281 {
282 const char *path = NULL;
283
284 if (c) {
285 path = c->http_path_query;
286 }
287 RETURN_STR_OR_EMPTY(path);
288 }
289
cddb_set_http_path_query(cddb_conn_t * c,const char * path)290 void cddb_set_http_path_query(cddb_conn_t *c, const char *path)
291 {
292 FREE_NOT_NULL(c->http_path_query);
293 c->http_path_query = strdup(path);
294 }
295
cddb_get_http_path_submit(const cddb_conn_t * c)296 const char *cddb_get_http_path_submit(const cddb_conn_t *c)
297 {
298 const char *path = NULL;
299
300 if (c) {
301 path = c->http_path_submit;
302 }
303 RETURN_STR_OR_EMPTY(path);
304 }
305
cddb_set_http_path_submit(cddb_conn_t * c,const char * path)306 void cddb_set_http_path_submit(cddb_conn_t *c, const char *path)
307 {
308 FREE_NOT_NULL(c->http_path_submit);
309 c->http_path_submit = strdup(path);
310 }
311
cddb_is_http_enabled(const cddb_conn_t * c)312 unsigned int cddb_is_http_enabled(const cddb_conn_t *c)
313 {
314 if (c) {
315 return c->is_http_enabled;
316 }
317 return FALSE;
318 }
319
cddb_http_enable(cddb_conn_t * c)320 void cddb_http_enable(cddb_conn_t *c)
321 {
322 c->is_http_enabled = TRUE;
323 cddb_errno_set(c, CDDB_ERR_OK);
324 }
325
cddb_http_disable(cddb_conn_t * c)326 void cddb_http_disable(cddb_conn_t *c)
327 {
328 c->is_http_enabled = FALSE;
329 cddb_errno_set(c, CDDB_ERR_OK);
330 }
331
cddb_is_http_proxy_enabled(const cddb_conn_t * c)332 unsigned int cddb_is_http_proxy_enabled(const cddb_conn_t *c)
333 {
334 if (c) {
335 return c->is_http_proxy_enabled;
336 }
337 return FALSE;
338 }
339
cddb_http_proxy_enable(cddb_conn_t * c)340 void cddb_http_proxy_enable(cddb_conn_t *c)
341 {
342 /* enabling HTTP proxy implies HTTP, but not vice versa */
343 cddb_http_enable(c);
344 c->is_http_proxy_enabled = TRUE;
345 cddb_errno_set(c, CDDB_ERR_OK);
346 }
347
cddb_http_proxy_disable(cddb_conn_t * c)348 void cddb_http_proxy_disable(cddb_conn_t *c)
349 {
350 c->is_http_proxy_enabled = FALSE;
351 cddb_errno_set(c, CDDB_ERR_OK);
352 }
353
cddb_get_http_proxy_server_name(const cddb_conn_t * c)354 const char *cddb_get_http_proxy_server_name(const cddb_conn_t *c)
355 {
356 const char *server = NULL;
357
358 if (c) {
359 server = c->http_proxy_server;
360 }
361 RETURN_STR_OR_EMPTY(server);
362 }
363
cddb_set_http_proxy_server_name(cddb_conn_t * c,const char * server)364 void cddb_set_http_proxy_server_name(cddb_conn_t *c, const char *server)
365 {
366 FREE_NOT_NULL(c->http_proxy_server);
367 c->http_proxy_server = strdup(server);
368 }
369
cddb_get_http_proxy_server_port(const cddb_conn_t * c)370 unsigned int cddb_get_http_proxy_server_port(const cddb_conn_t *c)
371 {
372 if (c) {
373 return c->http_proxy_server_port;
374 }
375 return 0;
376 }
377
cddb_set_http_proxy_server_port(cddb_conn_t * c,int port)378 void cddb_set_http_proxy_server_port(cddb_conn_t *c, int port)
379 {
380 c->http_proxy_server_port = port;
381 }
382
cddb_set_http_proxy_auth(cddb_conn_t * c,const char * username,const char * password)383 static void cddb_set_http_proxy_auth(cddb_conn_t *c,
384 const char *username, const char *password)
385 {
386 int len;
387 char *auth, *auth_b64;
388
389 FREE_NOT_NULL(c->http_proxy_auth);
390 len = 0;
391 if (username != NULL) {
392 len += strlen(username);
393 }
394 if (password != NULL) {
395 len += strlen(password);
396 }
397 len += 2; /* colon and 0-byte */;
398 auth = (char*)malloc(len);
399 snprintf(auth, len, "%s:%s",
400 (username ? username : ""),
401 (password ? password : ""));
402 auth_b64 = (char*)malloc(len * 2); /* certainly big enough */
403 cddb_b64_encode(auth_b64, auth);
404 c->http_proxy_auth = strdup(auth_b64);
405 free(auth_b64);
406 free(auth);
407 }
408
cddb_get_http_proxy_username(const cddb_conn_t * c)409 const char *cddb_get_http_proxy_username(const cddb_conn_t *c)
410 {
411 const char *user = NULL;
412
413 if (c) {
414 user = c->http_proxy_username;
415 }
416 RETURN_STR_OR_EMPTY(user);
417 }
418
cddb_set_http_proxy_username(cddb_conn_t * c,const char * username)419 void cddb_set_http_proxy_username(cddb_conn_t *c, const char *username)
420 {
421 FREE_NOT_NULL(c->http_proxy_username);
422 if (username) {
423 c->http_proxy_username = strdup(username);
424 }
425 /* remake authentication credentials */
426 cddb_set_http_proxy_auth(c, c->http_proxy_username, c->http_proxy_password);
427 }
428
cddb_get_http_proxy_password(const cddb_conn_t * c)429 const char *cddb_get_http_proxy_password(const cddb_conn_t *c)
430 {
431 const char *password = NULL;
432
433 if (c) {
434 password = c->http_proxy_password;
435 }
436 RETURN_STR_OR_EMPTY(password);
437 }
438
cddb_set_http_proxy_password(cddb_conn_t * c,const char * password)439 void cddb_set_http_proxy_password(cddb_conn_t *c, const char *password)
440 {
441 FREE_NOT_NULL(c->http_proxy_password);
442 if (password) {
443 c->http_proxy_password = strdup(password);
444 }
445 /* remake authentication credentials */
446 cddb_set_http_proxy_auth(c, c->http_proxy_username, c->http_proxy_password);
447 }
448
cddb_set_http_proxy_credentials(cddb_conn_t * c,const char * username,const char * password)449 void cddb_set_http_proxy_credentials(cddb_conn_t* c,
450 const char *username, const char* password)
451 {
452 /* remove cleartext credentials */
453 FREE_NOT_NULL(c->http_proxy_username);
454 FREE_NOT_NULL(c->http_proxy_password);
455 /* remake authentication credentials */
456 cddb_set_http_proxy_auth(c, username, password);
457 }
458
cddb_errno(const cddb_conn_t * c)459 cddb_error_t cddb_errno(const cddb_conn_t *c)
460 {
461 if (c) {
462 return c->errnum;
463 }
464 return CDDB_ERR_INVALID;
465 }
466
cddb_set_client(cddb_conn_t * c,const char * cname,const char * cversion)467 void cddb_set_client(cddb_conn_t *c, const char *cname, const char *cversion)
468 {
469 if (cname && cversion) {
470 FREE_NOT_NULL(c->cname);
471 FREE_NOT_NULL(c->cversion);
472 c->cname = strdup(cname);
473 c->cversion = strdup(cversion);
474 }
475 }
476
cddb_set_email_address(cddb_conn_t * c,const char * email)477 int cddb_set_email_address(cddb_conn_t *c, const char *email)
478 {
479 char *at;
480 int len;
481
482 cddb_log_debug("cddb_set_email_address()");
483 if ((email == NULL) ||
484 ((at = strchr(email, '@')) == NULL) ||
485 (at == email) ||
486 (*(at+1) == '\0')) {
487 cddb_errno_log_error(c, CDDB_ERR_EMAIL_INVALID);
488 return FALSE;
489 }
490 /* extract user name */
491 FREE_NOT_NULL(c->user);
492 len = at - email;
493 c->user = malloc(len + 1);
494 strncpy(c->user, email, len);
495 c->user[len] = '\0';
496 /* extract host name */
497 at++;
498 FREE_NOT_NULL(c->hostname);
499 c->hostname = strdup(at);
500 cddb_log_debug("...user name = '%s'", c->user);
501 cddb_log_debug("...host name = '%s'", c->hostname);
502
503 return TRUE;
504 }
505
cddb_cache_mode(const cddb_conn_t * c)506 cddb_cache_mode_t cddb_cache_mode(const cddb_conn_t *c)
507 {
508 if (c) {
509 return c->use_cache;
510 }
511 return CACHE_OFF;
512 }
513
cddb_cache_enable(cddb_conn_t * c)514 void cddb_cache_enable(cddb_conn_t *c)
515 {
516 if (c) {
517 c->use_cache = CACHE_ON;
518 }
519 }
520
cddb_cache_only(cddb_conn_t * c)521 void cddb_cache_only(cddb_conn_t *c)
522 {
523 if (c) {
524 c->use_cache = CACHE_ONLY;
525 }
526 }
527
cddb_cache_disable(cddb_conn_t * c)528 void cddb_cache_disable(cddb_conn_t *c)
529 {
530 if (c) {
531 c->use_cache = CACHE_OFF;
532 }
533 }
534
cddb_cache_get_dir(const cddb_conn_t * c)535 const char *cddb_cache_get_dir(const cddb_conn_t *c)
536 {
537 if (c) {
538 return c->cache_dir;;
539 }
540 return NULL;
541 }
542
cddb_cache_set_dir(cddb_conn_t * c,const char * dir)543 int cddb_cache_set_dir(cddb_conn_t *c, const char *dir)
544 {
545 char *home;
546
547 cddb_log_debug("cddb_cache_set_dir()");
548 if (dir) {
549 FREE_NOT_NULL(c->cache_dir);
550 if (dir[0] == '~') {
551 /* expand ~ to $HOME */
552 home = getenv("HOME");
553 if (home) {
554 c->cache_dir = (char*)malloc(strlen(home) + strlen(dir));
555 sprintf(c->cache_dir, "%s%s", home, dir + 1);
556 }
557 } else {
558 c->cache_dir = strdup(dir);
559 }
560 }
561 return TRUE;
562 }
563
cddb_first_site(cddb_conn_t * c)564 const cddb_site_t *cddb_first_site(cddb_conn_t *c)
565 {
566 elem_t *e;
567
568 e = list_first(c->sites_data);
569 if (e) {
570 return element_data(e);
571 }
572 return NULL;
573 }
574
cddb_next_site(cddb_conn_t * c)575 const cddb_site_t *cddb_next_site(cddb_conn_t *c)
576 {
577 elem_t *e;
578
579 e = list_next(c->sites_data);
580 if (e) {
581 return element_data(e);
582 }
583 return NULL;
584 }
585
cddb_search_set_fields(cddb_conn_t * c,unsigned int fields)586 void cddb_search_set_fields(cddb_conn_t *c, unsigned int fields)
587 {
588 c->srch.fields = fields;
589 }
590
cddb_search_set_categories(cddb_conn_t * c,unsigned int cats)591 void cddb_search_set_categories(cddb_conn_t *c, unsigned int cats)
592 {
593 c->srch.cats = cats;
594 }
595
596 /* --- connecting / disconnecting --- */
597
598
cddb_handshake(cddb_conn_t * c)599 static int cddb_handshake(cddb_conn_t *c)
600 {
601 char *msg;
602 int code;
603
604 cddb_log_debug("cddb_handshake()");
605 /* check sign-on banner */
606 switch (code = cddb_get_response_code(c, &msg)) {
607 case -1:
608 return FALSE;
609 case 200: /* read/write */
610 case 201: /* read only */
611 break;
612 case 432:
613 case 433:
614 case 434:
615 cddb_errno_log_error(c, CDDB_ERR_PERMISSION_DENIED);
616 return FALSE;
617 }
618
619 /* send hello and check response */
620 if (!cddb_send_cmd(c, CMD_HELLO, c->user, c->hostname, c->cname, c->cversion)) {
621 return FALSE;
622 }
623 switch (code = cddb_get_response_code(c, &msg)) {
624 case -1:
625 return FALSE;
626 case 200: /* ok */
627 case 402: /* already shook hands */
628 break;
629 case 431:
630 cddb_errno_log_error(c, CDDB_ERR_PERMISSION_DENIED);
631 return FALSE;
632 }
633
634 /* set protocol level */
635 if (!cddb_send_cmd(c, CMD_PROTO, DEFAULT_PROTOCOL_VERSION)) {
636 return FALSE;
637 }
638 switch (code = cddb_get_response_code(c, &msg)) {
639 case -1:
640 return FALSE;
641 case 200: /* ok */
642 case 201: /* ok */
643 case 502: /* protocol already set */
644 break;
645 case 501: /* illegal protocol level */
646 /* ignore */
647 break;
648 }
649
650 cddb_errno_set(c, CDDB_ERR_OK);
651 return TRUE;
652 }
653
cddb_connect(cddb_conn_t * c)654 int cddb_connect(cddb_conn_t *c)
655 {
656 int rv = TRUE;
657
658 cddb_log_debug("cddb_connect()");
659 if (!CONNECTION_OK(c)) {
660 struct hostent *he;
661
662 /* resolve host name */
663 if (c->is_http_proxy_enabled) {
664 /* use HTTP proxy server name */
665 he = timeout_gethostbyname(c->http_proxy_server, c->timeout);
666 c->sa.sin_port = htons(c->http_proxy_server_port);
667 } else {
668 /* use CDDB server name */
669 he = timeout_gethostbyname(c->server_name, c->timeout);
670 c->sa.sin_port = htons(c->server_port);
671 }
672 if (he == NULL) {
673 cddb_errno_log_error(c, CDDB_ERR_UNKNOWN_HOST_NAME);
674 return FALSE;
675 }
676 /* initialize socket address */
677 c->sa.sin_family = AF_INET;
678 c->sa.sin_addr = *((struct in_addr*)he->h_addr);
679 memset(&(c->sa.sin_zero), 0, sizeof(c->sa.sin_zero));
680
681 if ((c->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
682 cddb_errno_log_error(c, CDDB_ERR_CONNECT);
683 return FALSE;
684 }
685
686 rv = timeout_connect(c->socket, (struct sockaddr*)&(c->sa),
687 sizeof(struct sockaddr), c->timeout);
688 if (rv == -1) {
689 cddb_errno_log_error(c, CDDB_ERR_CONNECT);
690 return FALSE;
691 }
692
693 if (!c->is_http_enabled) {
694 /* send handshake message to CDDB server (CDDBP only) */
695 return cddb_handshake(c);
696 }
697 }
698
699 cddb_errno_set(c, CDDB_ERR_OK);
700 return TRUE;
701 }
702
cddb_disconnect(cddb_conn_t * c)703 void cddb_disconnect(cddb_conn_t *c)
704 {
705 cddb_log_debug("cddb_disconnect()");
706 if (CONNECTION_OK(c)) {
707 close(c->socket);
708 c->socket = -1;
709 }
710 cddb_errno_set(c, CDDB_ERR_OK);
711 }
712
713
714 /* --- miscellaneous --- */
715
716
cddb_clone_proxy(cddb_conn_t * dst,cddb_conn_t * src)717 void cddb_clone_proxy(cddb_conn_t *dst, cddb_conn_t *src)
718 {
719 if (cddb_is_http_proxy_enabled(src)) {
720 /* XXX: optimize? */
721 FREE_NOT_NULL(dst->http_proxy_server);
722 if (src->http_proxy_server) {
723 dst->http_proxy_server = strdup(src->http_proxy_server);
724 }
725 dst->http_proxy_server_port = src->http_proxy_server_port;
726 FREE_NOT_NULL(dst->http_proxy_auth);
727 if (src->http_proxy_auth) {
728 dst->http_proxy_auth = strdup(src->http_proxy_auth);
729 }
730 cddb_http_proxy_enable(dst);
731 }
732 }
733