summaryrefslogtreecommitdiffstats
path: root/lib/libshout-idjc/src/shout.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libshout-idjc/src/shout.c')
-rw-r--r--lib/libshout-idjc/src/shout.c1756
1 files changed, 942 insertions, 814 deletions
diff --git a/lib/libshout-idjc/src/shout.c b/lib/libshout-idjc/src/shout.c
index d296ff3321..9cc169909e 100644
--- a/lib/libshout-idjc/src/shout.c
+++ b/lib/libshout-idjc/src/shout.c
@@ -22,7 +22,7 @@
*/
#ifdef HAVE_CONFIG_H
- #include <config.h>
+# include <config.h>
#endif
#include <stdarg.h>
@@ -32,27 +32,28 @@
#include <strings.h>
#include <errno.h>
-#include <shout/shout.h>
+#include <shoutidjc/shout.h>
+
#include <common/net/sock.h>
-#include "common/timing/timing.h"
-#include "common/httpp/httpp.h"
+#include <common/timing/timing.h>
+#include <common/httpp/httpp.h>
#include "shout_private.h"
#include "util.h"
#ifdef _MSC_VER
-# ifndef va_copy
-# define va_copy(ap1, ap2) memcpy(&ap1, &ap2, sizeof(va_list))
-# endif
-# define vsnprintf _vsnprintf
-# define inline _inline
+# ifndef va_copy
+# define va_copy(ap1, ap2) memcpy(&ap1, &ap2, sizeof(va_list))
+# endif
+# define vsnprintf _vsnprintf
+# define inline _inline
#endif
/* -- local prototypes -- */
static int send_queue(shout_t *self);
static int get_response(shout_t *self);
-static int try_connect (shout_t *self);
-static int try_write (shout_t *self, const void *data, size_t len);
+static int try_connect(shout_t *self);
+static int try_write(shout_t *self, const void *data, size_t len);
static int create_request(shout_t *self);
static int parse_response(shout_t *self);
@@ -64,474 +65,504 @@ static int _initialized = 0;
void shout_init(void)
{
- if (_initialized)
- return;
+ if (_initialized)
+ return;
- sock_initialize();
- _initialized = 1;
+ sock_initialize();
+ _initialized = 1;
}
void shout_shutdown(void)
{
- if (!_initialized)
- return;
+ if (!_initialized)
+ return;
- sock_shutdown();
- _initialized = 0;
+ sock_shutdown();
+ _initialized = 0;
}
shout_t *shout_new(void)
{
- shout_t *self;
+ shout_t *self;
- /* in case users haven't done this explicitly. Should we error
- * if not initialized instead? */
- shout_init();
-
- if (!(self = (shout_t *)calloc(1, sizeof(shout_t)))) {
- return NULL;
- }
+ /* in case users haven't done this explicitly. Should we error
+ * if not initialized instead? */
+ shout_init();
- if (shout_set_host(self, LIBSHOUT_DEFAULT_HOST) != SHOUTERR_SUCCESS) {
- shout_free(self);
+ if (!(self = (shout_t*)calloc(1, sizeof(shout_t)))) {
+ return NULL;
+ }
- return NULL;
- }
- if (shout_set_user(self, LIBSHOUT_DEFAULT_USER) != SHOUTERR_SUCCESS) {
- shout_free(self);
+ if (shout_set_host(self, LIBSHOUT_DEFAULT_HOST) != SHOUTERR_SUCCESS) {
+ shout_free(self);
+ return NULL;
+ }
- return NULL;
- }
- if (shout_set_agent(self, LIBSHOUT_DEFAULT_USERAGENT) != SHOUTERR_SUCCESS) {
- shout_free(self);
+ if (shout_set_user(self, LIBSHOUT_DEFAULT_USER) != SHOUTERR_SUCCESS) {
+ shout_free(self);
+ return NULL;
+ }
- return NULL;
- }
- if (!(self->audio_info = _shout_util_dict_new())) {
- shout_free(self);
+ if (shout_set_agent(self, LIBSHOUT_DEFAULT_USERAGENT) != SHOUTERR_SUCCESS) {
+ shout_free(self);
+ return NULL;
+ }
- return NULL;
- }
- if (!(self->meta = _shout_util_dict_new())) {
- shout_free(self);
+ if (!(self->audio_info = _shout_util_dict_new())) {
+ shout_free(self);
+ return NULL;
+ }
- return NULL;
- }
- if (shout_set_meta(self, "name", "no name") != SHOUTERR_SUCCESS) {
- shout_free(self);
+ if (!(self->meta = _shout_util_dict_new())) {
+ shout_free(self);
+ return NULL;
+ }
- return NULL;
- }
+ if (shout_set_meta(self, "name", "no name") != SHOUTERR_SUCCESS) {
+ shout_free(self);
+ return NULL;
+ }
#ifdef HAVE_OPENSSL
- if (shout_set_allowed_ciphers(self, LIBSHOUT_DEFAULT_ALLOWED_CIPHERS) != SHOUTERR_SUCCESS) {
- shout_free(self);
+ if (shout_set_allowed_ciphers(self, LIBSHOUT_DEFAULT_ALLOWED_CIPHERS) != SHOUTERR_SUCCESS) {
+ shout_free(self);
+ return NULL;
+ }
- return NULL;
- }
- self->tls_mode = SHOUT_TLS_AUTO;
+ self->tls_mode = SHOUT_TLS_AUTO;
+ self->tls_mode_used = SHOUTERR_NOTLS;
#endif
- self->port = LIBSHOUT_DEFAULT_PORT;
- self->format = LIBSHOUT_DEFAULT_FORMAT;
- self->protocol = LIBSHOUT_DEFAULT_PROTOCOL;
+ self->port = LIBSHOUT_DEFAULT_PORT;
+ self->format = LIBSHOUT_DEFAULT_FORMAT;
+ self->protocol = LIBSHOUT_DEFAULT_PROTOCOL;
- return self;
+ return self;
}
void shout_free(shout_t *self)
{
- if (!self) return;
-
- if (self->state != SHOUT_STATE_UNCONNECTED) return;
-
- if (self->host) free(self->host);
- if (self->password) free(self->password);
- if (self->mount) free(self->mount);
- if (self->user) free(self->user);
- if (self->useragent) free(self->useragent);
- if (self->audio_info) _shout_util_dict_free (self->audio_info);
- if (self->meta) _shout_util_dict_free (self->meta);
+ if (!self)
+ return;
+
+ if (self->state != SHOUT_STATE_UNCONNECTED)
+ return;
+
+ if (self->host)
+ free(self->host);
+ if (self->password)
+ free(self->password);
+ if (self->mount)
+ free(self->mount);
+ if (self->user)
+ free(self->user);
+ if (self->useragent)
+ free(self->useragent);
+ if (self->audio_info)
+ _shout_util_dict_free (self->audio_info);
+ if (self->meta)
+ _shout_util_dict_free (self->meta);
#ifdef HAVE_OPENSSL
- if (self->ca_directory) free(self->ca_directory);
- if (self->ca_file) free(self->ca_file);
- if (self->allowed_ciphers) free(self->allowed_ciphers);
- if (self->client_certificate) free(self->client_certificate);
+ if (self->ca_directory)
+ free(self->ca_directory);
+ if (self->ca_file)
+ free(self->ca_file);
+ if (self->allowed_ciphers)
+ free(self->allowed_ciphers);
+ if (self->client_certificate)
+ free(self->client_certificate);
#endif
- free(self);
+ free(self);
}
int shout_open(shout_t *self)
{
- /* sanity check */
- if (!self)
- return SHOUTERR_INSANE;
- if (self->state != SHOUT_STATE_UNCONNECTED)
- return SHOUTERR_CONNECTED;
- if (!self->host || !self->password || !self->port)
- return self->error = SHOUTERR_INSANE;
- if (self->format == SHOUT_FORMAT_OGG && (self->protocol != SHOUT_PROTOCOL_HTTP && self->protocol != SHOUT_PROTOCOL_ROARAUDIO))
- return self->error = SHOUTERR_UNSUPPORTED;
+ /* sanity check */
+ if (!self)
+ return SHOUTERR_INSANE;
+ if (self->state != SHOUT_STATE_UNCONNECTED)
+ return SHOUTERR_CONNECTED;
+ if (!self->host || !self->password || !self->port)
+ return self->error = SHOUTERR_INSANE;
+ if (self->format == SHOUT_FORMAT_OGG && (self->protocol != SHOUT_PROTOCOL_HTTP && self->protocol != SHOUT_PROTOCOL_ROARAUDIO))
+ return self->error = SHOUTERR_UNSUPPORTED;
- return self->error = try_connect(self);
+ return self->error = try_connect(self);
}
int shout_close(shout_t *self)
{
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- if (self->state == SHOUT_STATE_UNCONNECTED)
- return self->error = SHOUTERR_UNCONNECTED;
+ if (self->state == SHOUT_STATE_UNCONNECTED)
+ return self->error = SHOUTERR_UNCONNECTED;
- if (self->state == SHOUT_STATE_CONNECTED && self->close)
- self->close(self);
+ if (self->state == SHOUT_STATE_CONNECTED && self->close)
+ self->close(self);
#ifdef HAVE_OPENSSL
- if (self->tls)
- shout_tls_close(self->tls);
- self->tls = NULL;
+ if (self->tls)
+ shout_tls_close(self->tls);
+ self->tls = NULL;
#endif
- sock_close(self->socket);
- self->state = SHOUT_STATE_UNCONNECTED;
- self->starttime = 0;
- self->senttime = 0;
- shout_queue_free(&self->rqueue);
- shout_queue_free(&self->wqueue);
+ sock_close(self->socket);
+ self->state = SHOUT_STATE_UNCONNECTED;
+ self->starttime = 0;
+ self->senttime = 0;
+ shout_queue_free(&self->rqueue);
+ shout_queue_free(&self->wqueue);
- return self->error = SHOUTERR_SUCCESS;
+ return self->error = SHOUTERR_SUCCESS;
}
int shout_send(shout_t *self, const unsigned char *data, size_t len)
{
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- if (self->state != SHOUT_STATE_CONNECTED)
- return self->error = SHOUTERR_UNCONNECTED;
+ if (self->state != SHOUT_STATE_CONNECTED)
+ return self->error = SHOUTERR_UNCONNECTED;
- if (self->starttime <= 0)
- self->starttime = timing_get_time();
+ if (self->starttime <= 0)
+ self->starttime = timing_get_time();
- if (!len)
- return send_queue(self);
+ if (!len)
+ return send_queue(self);
- return self->send(self, data, len);
+ return self->send(self, data, len);
}
ssize_t shout_send_raw(shout_t *self, const unsigned char *data, size_t len)
{
- ssize_t ret;
-
- if (!self)
- return SHOUTERR_INSANE;
+ ssize_t ret;
- if (self->state != SHOUT_STATE_CONNECTED)
- return SHOUTERR_UNCONNECTED;
+ if (!self)
+ return SHOUTERR_INSANE;
- self->error = SHOUTERR_SUCCESS;
+ if (self->state != SHOUT_STATE_CONNECTED)
+ return SHOUTERR_UNCONNECTED;
- /* send immediately if possible (should be the common case) */
- if (len && ! self->wqueue.len) {
- if ((ret = try_write(self, data, len)) < 0)
- return self->error;
- if (ret < (ssize_t)len) {
- self->error = shout_queue_data(&self->wqueue, data + ret, len - ret);
- if (self->error != SHOUTERR_SUCCESS)
- return self->error;
- }
+ self->error = SHOUTERR_SUCCESS;
- return len;
- }
+ /* send immediately if possible (should be the common case) */
+ if (len && !self->wqueue.len) {
+ if ((ret = try_write(self, data, len)) < 0)
+ return self->error;
+ if (ret < (ssize_t)len) {
+ self->error = shout_queue_data(&self->wqueue, data + ret, len - ret);
+ if (self->error != SHOUTERR_SUCCESS)
+ return self->error;
+ }
+ return len;
+ }
- self->error = shout_queue_data(&self->wqueue, data, len);
- if (self->error != SHOUTERR_SUCCESS)
- return self->error;
+ self->error = shout_queue_data(&self->wqueue, data, len);
+ if (self->error != SHOUTERR_SUCCESS)
+ return self->error;
- ret = send_queue(self);
- if (ret == SHOUTERR_SUCCESS || (len && ret == SHOUTERR_BUSY))
- return len;
+ ret = send_queue(self);
+ if (ret == SHOUTERR_SUCCESS || (len && ret == SHOUTERR_BUSY))
+ return len;
- return ret;
+ return ret;
}
ssize_t shout_queuelen(shout_t *self)
{
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- return (ssize_t)self->wqueue.len;
+ return (ssize_t)self->wqueue.len;
}
void shout_sync(shout_t *self)
{
- int64_t sleep;
+ int64_t sleep;
+
+ if (!self)
+ return;
- if (!self)
- return;
+ if (self->senttime == 0)
+ return;
- if (self->senttime == 0)
- return;
+ sleep = self->senttime / 1000 - (timing_get_time() - self->starttime);
+ if (sleep > 0)
+ timing_sleep((uint64_t)sleep);
- sleep = self->senttime / 1000 - (timing_get_time() - self->starttime);
- if (sleep > 0)
- timing_sleep((uint64_t)sleep);
-
}
int shout_delay(shout_t *self)
{
- if (!self)
- return 0;
+ if (!self)
+ return 0;
- if (self->senttime == 0)
- return 0;
+ if (self->senttime == 0)
+ return 0;
- return self->senttime / 1000 - (timing_get_time() - self->starttime);
+ return self->senttime / 1000 - (timing_get_time() - self->starttime);
}
-
+
shout_metadata_t *shout_metadata_new(void)
{
- return _shout_util_dict_new();
+ return _shout_util_dict_new();
}
void shout_metadata_free(shout_metadata_t *self)
{
- if (!self)
- return;
+ if (!self)
+ return;
- _shout_util_dict_free(self);
+ _shout_util_dict_free(self);
}
int shout_metadata_add(shout_metadata_t *self, const char *name, const char *value)
{
- if (!self || !name)
- return SHOUTERR_INSANE;
+ if (!self || !name)
+ return SHOUTERR_INSANE;
- return _shout_util_dict_set(self, name, value);
+ return _shout_util_dict_set(self, name, value);
}
/* open second socket to server, send HTTP request to change metadata.
- * TODO: prettier error-handling. */
+ * TODO: prettier error-handling.
+ */
int shout_set_metadata(shout_t *self, shout_metadata_t *metadata)
{
- int error;
- sock_t socket = -1;
- int rv;
- char *encvalue = NULL;
- const char *request_template;
- char *request = NULL;
- size_t request_len;
- char *auth = NULL;
+ int error;
+ sock_t socket = -1;
+ int rv;
+ char *encvalue = NULL;
+ const char *request_template;
+ char *request = NULL;
+ size_t request_len;
+ char *auth = NULL;
+ char *mount = NULL;
#ifdef HAVE_OPENSSL
- shout_tls_t *tls = NULL;
+ shout_tls_t *tls = NULL;
#endif
- if (!self || !metadata)
- return SHOUTERR_INSANE;
-
- if (!(encvalue = _shout_util_dict_urlencode(metadata, '&')))
- goto error_malloc;
-
- switch (self->protocol) {
- case SHOUT_PROTOCOL_ICY:
- request_template = "GET /admin.cgi?mode=updinfo&pass=%s&%s HTTP/1.0\r\nUser-Agent: %s (Mozilla compatible)\r\n\r\n";
- request_len = strlen(request_template) + strlen(self->password) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1;
- if (!(request = malloc(request_len)))
- goto error_malloc;
- snprintf(request, request_len, request_template, self->password, encvalue, shout_get_agent(self));
- break;
- case SHOUT_PROTOCOL_HTTP:
- auth = shout_http_basic_authorization(self);
-
- request_template = "GET /admin/metadata?mode=updinfo&mount=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n%s\r\n";
- request_len = strlen(request_template) + strlen(self->mount) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1;
- if (auth)
- request_len += strlen(auth);
- if (!(request = malloc(request_len)))
- goto error_malloc;
- snprintf(request, request_len, request_template, self->mount, encvalue, shout_get_agent(self), auth ? auth : "");
- break;
- default:
- request_template = "GET /admin.cgi?mode=updinfo&pass=%s&mount=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n\r\n";
- request_len = strlen(request_template) + strlen(self->password) + strlen(self->mount) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1;
- if (!(request = malloc(request_len)))
- goto error_malloc;
- snprintf(request, request_len, request_template, self->password, self->mount, encvalue, shout_get_agent(self));
- break;
- }
+ if (!self || !metadata)
+ return SHOUTERR_INSANE;
+
+ if (!(encvalue = _shout_util_dict_urlencode(metadata, '&')))
+ goto error_malloc;
+
+ if (!(mount = _shout_util_url_encode(self->mount)))
+ goto error_malloc;
+
+ switch (self->protocol) {
+ case SHOUT_PROTOCOL_ICY:
+ request_template = "GET /admin.cgi?mode=updinfo&pass=%s&%s HTTP/1.0\r\nUser-Agent: %s (Mozilla compatible)\r\n\r\n";
+ request_len = strlen(request_template) + strlen(self->password) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1;
+ if (!(request = malloc(request_len)))
+ goto error_malloc;
+ snprintf(request, request_len, request_template, self->password, encvalue, shout_get_agent(self));
+ break;
+ case SHOUT_PROTOCOL_HTTP:
+ auth = shout_http_basic_authorization(self);
+
+ request_template = "GET /admin/metadata?mode=updinfo&mount=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n%s\r\n";
+ request_len = strlen(request_template) + strlen(mount) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1;
+ if (auth)
+ request_len += strlen(auth);
+ if (!(request = malloc(request_len)))
+ goto error_malloc;
+ snprintf(request, request_len, request_template, mount, encvalue, shout_get_agent(self), auth ? auth : "");
+ break;
+ default:
+ request_template = "GET /admin.cgi?mode=updinfo&pass=%s&mount=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n\r\n";
+ request_len = strlen(request_template) + strlen(self->password) + strlen(mount) + strlen(encvalue) + strlen(shout_get_agent(self)) + 1;
+ if (!(request = malloc(request_len)))
+ goto error_malloc;
+ snprintf(request, request_len, request_template, self->password, mount, encvalue, shout_get_agent(self));
+ break;
+ }
+
+ free(encvalue);
+ encvalue = NULL;
- free(encvalue);
- encvalue = NULL;
+ free(mount);
+ mount = NULL;
- if (auth)
- free(auth);
- auth = NULL;
+ if (auth)
+ free(auth);
+ auth = NULL;
- if ((socket = sock_connect(self->host, self->port)) <= 0)
- return SHOUTERR_NOCONNECT;
+ if ((socket = sock_connect(self->host, self->port)) <= 0)
+ return SHOUTERR_NOCONNECT;
#ifdef HAVE_OPENSSL
- switch (self->tls_mode) {
- case SHOUT_TLS_DISABLED:
- /* nothing to do */
- break;
- case SHOUT_TLS_RFC2817: /* Use TLS via HTTP Upgrade:-header [RFC2817]. */
- do { /* use a subscope to avoid more function level variables */
- char upgrade[512];
- size_t len;
-
- /* send upgrade request */
- snprintf(upgrade, sizeof(upgrade),
- "GET / HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: TLS/1.0\r\nHost: %s:%i\r\n\r\n",
- self->host, self->port);
- upgrade[sizeof(upgrade)-1] = 0;
- len = strlen(upgrade);
- if (len == (sizeof(upgrade) - 1))
- goto error_malloc;
- rv = sock_write_bytes(socket, upgrade, len);
- if (len != (size_t)rv)
- goto error_socket;
-
- /* read status line */
- if (!sock_read_line(socket, upgrade, sizeof(upgrade)))
- goto error_socket;
- if (strncmp(upgrade, "HTTP/1.1 101 ", 13) != 0)
- goto error_socket;
-
- /* read headers */
- len = 0;
- do {
- if (!sock_read_line(socket, upgrade, sizeof(upgrade)))
- goto error_socket;
- if (upgrade[0] == 0)
- break;
- if (!strncasecmp(upgrade, "Content-Length: ", 16) == 0)
- len = atoi(upgrade + 16);
- } while (1);
-
- /* read body */
- while (len) {
- rv = sock_read_bytes(socket, upgrade, len > sizeof(upgrade) ? sizeof(upgrade) : len);
- if (rv < 1)
- goto error_socket;
- len -= rv;
- }
- } while (0);
- /* fall thru */
- case SHOUT_TLS_RFC2818: /* Use TLS for transport layer like HTTPS [RFC2818] does. */
- tls = shout_tls_new(self, socket);
- if (!tls)
- goto error_malloc;
- error = shout_tls_try_connect(tls);
- if (error != SHOUTERR_SUCCESS)
- goto error;
- break;
- default:
- /* Bad mode or auto detection not completed. */
- error = SHOUTERR_INSANE;
- goto error;
- break;
- }
+ switch (self->tls_mode_used) {
+ case SHOUT_TLS_DISABLED:
+ /* nothing to do */
+ break;
+
+ case SHOUT_TLS_RFC2817:
+ /* Use TLS via HTTP Upgrade:-header [RFC2817]. */
+ do {
+ /* use a subscope to avoid more function level variables */
+ char upgrade[512];
+ size_t len;
+
+ /* send upgrade request */
+ snprintf(upgrade, sizeof(upgrade),
+ "GET / HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: TLS/1.0\r\nHost: %s:%i\r\n\r\n",
+ self->host, self->port);
+
+ upgrade[sizeof(upgrade) - 1] = 0;
+ len = strlen(upgrade);
+ if (len == (sizeof(upgrade) - 1))
+ goto error_malloc;
+
+ rv = sock_write_bytes(socket, upgrade, len);
+ if (len != (size_t)rv)
+ goto error_socket;
+
+ /* read status line */
+ if (!sock_read_line(socket, upgrade, sizeof(upgrade)))
+ goto error_socket;
+ if (strncmp(upgrade, "HTTP/1.1 101 ", 13) != 0)
+ goto error_socket;
+
+ /* read headers */
+ len = 0;
+ do {
+ if (!sock_read_line(socket, upgrade, sizeof(upgrade)))
+ goto error_socket;
+ if (upgrade[0] == 0)
+ break;
+ if (!strncasecmp(upgrade, "Content-Length: ", 16) == 0)
+ len = atoi(upgrade + 16);
+ } while (1);
+
+ /* read body */
+ while (len) {
+ rv = sock_read_bytes(socket, upgrade, len > sizeof(upgrade) ? sizeof(upgrade) : len);
+ if (rv < 1)
+ goto error_socket;
+ len -= rv;
+ }
+ } while (0);
+ /* fall thru */
+
+ case SHOUT_TLS_RFC2818:
+ /* Use TLS for transport layer like HTTPS [RFC2818] does. */
+ tls = shout_tls_new(self, socket);
+ if (!tls)
+ goto error_malloc;
+ error = shout_tls_try_connect(tls);
+ if (error != SHOUTERR_SUCCESS)
+ goto error;
+ break;
+
+ default:
+ /* Bad mode or auto detection not completed. */
+ error = SHOUTERR_INSANE;
+ goto error;
+ break;
+ }
#endif
#ifdef HAVE_OPENSSL
- if (tls) {
- rv = shout_tls_write(tls, request, strlen(request));
- } else {
- rv = sock_write(socket, "%s", request);
- }
+ if (tls) {
+ rv = shout_tls_write(tls, request, strlen(request));
+ } else {
+ rv = sock_write(socket, "%s", request);
+ }
#else
- rv = sock_write(socket, "%s", request);
+ rv = sock_write(socket, "%s", request);
#endif
- if (!rv)
- goto error_socket;
+ if (!rv)
+ goto error_socket;
- error = SHOUTERR_SUCCESS;
- goto error;
+ error = SHOUTERR_SUCCESS;
+ goto error;
error_socket:
- error = SHOUTERR_SOCKET;
- goto error;
+ error = SHOUTERR_SOCKET;
+ goto error;
error_malloc:
- error = SHOUTERR_MALLOC;
- goto error;
+ error = SHOUTERR_MALLOC;
+ goto error;
error:
#ifdef HAVE_OPENSSL
- if (tls)
- shout_tls_close(tls);
+ if (tls)
+ shout_tls_close(tls);
#endif
- if (socket != -1)
- sock_close(socket);
- if (encvalue)
- free(encvalue);
- if (request)
- free(request);
- if (auth)
- free(auth);
- return error;
+ if (socket != -1)
+ sock_close(socket);
+ if (encvalue)
+ free(encvalue);
+ if (request)
+ free(request);
+ if (auth)
+ free(auth);
+ if (mount)
+ free(mount);
+ return error;
}
/* getters/setters */
const char *shout_version(int *major, int *minor, int *patch)
{
- if (major)
- *major = LIBSHOUT_MAJOR;
- if (minor)
- *minor = LIBSHOUT_MINOR;
- if (patch)
- *patch = LIBSHOUT_MICRO;
+ if (major)
+ *major = LIBSHOUT_MAJOR;
+ if (minor)
+ *minor = LIBSHOUT_MINOR;
+ if (patch)
+ *patch = LIBSHOUT_MICRO;
- return VERSION;
+ return VERSION;
}
int shout_get_errno(shout_t *self)
{
- return self->error;
+ return self->error;
}
const char *shout_get_error(shout_t *self)
{
- if (!self)
- return "Invalid shout_t";
-
- switch (self->error) {
- case SHOUTERR_SUCCESS:
- return "No error";
- case SHOUTERR_INSANE:
- return "Nonsensical arguments";
- case SHOUTERR_NOCONNECT:
- return "Couldn't connect";
- case SHOUTERR_NOLOGIN:
- return "Login failed";
- case SHOUTERR_SOCKET:
- return "Socket error";
- case SHOUTERR_MALLOC:
- return "Out of memory";
- case SHOUTERR_CONNECTED:
- return "Cannot set parameter while connected";
- case SHOUTERR_UNCONNECTED:
- return "Not connected";
- case SHOUTERR_BUSY:
- return "Socket is busy";
- case SHOUTERR_UNSUPPORTED:
- return "This libshout doesn't support the requested option";
- case SHOUTERR_NOTLS:
- return "TLS requested but not supported by peer";
- case SHOUTERR_TLSBADCERT:
- return "TLS connection can not be established because of bad certificate";
- case SHOUTERR_RETRY:
- return "Please retry current operation.";
- default:
- return "Unknown error";
- }
+ if (!self)
+ return "Invalid shout_t";
+
+ switch (self->error) {
+ case SHOUTERR_SUCCESS:
+ return "No error";
+ case SHOUTERR_INSANE:
+ return "Nonsensical arguments";
+ case SHOUTERR_NOCONNECT:
+ return "Couldn't connect";
+ case SHOUTERR_NOLOGIN:
+ return "Login failed";
+ case SHOUTERR_SOCKET:
+ return "Socket error";
+ case SHOUTERR_MALLOC:
+ return "Out of memory";
+ case SHOUTERR_CONNECTED:
+ return "Cannot set parameter while connected";
+ case SHOUTERR_UNCONNECTED:
+ return "Not connected";
+ case SHOUTERR_BUSY:
+ return "Socket is busy";
+ case SHOUTERR_UNSUPPORTED:
+ return "This libshout doesn't support the requested option";
+ case SHOUTERR_NOTLS:
+ return "TLS requested but not supported by peer";
+ case SHOUTERR_TLSBADCERT:
+ return "TLS connection can not be established because of bad certificate";
+ case SHOUTERR_RETRY:
+ return "Please retry current operation.";
+ default:
+ return "Unknown error";
+ }
}
/* Returns:
@@ -541,759 +572,855 @@ const char *shout_get_error(shout_t *self)
*/
int shout_get_connected(shout_t *self)
{
- int rc;
+ int rc;
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- if (self->state == SHOUT_STATE_CONNECTED)
- return SHOUTERR_CONNECTED;
- if (self->state != SHOUT_STATE_UNCONNECTED) {
- if ((rc = try_connect(self)) == SHOUTERR_SUCCESS)
- return SHOUTERR_CONNECTED;
- return rc;
- }
+ if (self->state == SHOUT_STATE_CONNECTED)
+ return SHOUTERR_CONNECTED;
+ if (self->state != SHOUT_STATE_UNCONNECTED) {
+ if ((rc = try_connect(self)) == SHOUTERR_SUCCESS)
+ return SHOUTERR_CONNECTED;
+ return rc;
+ }
- return SHOUTERR_UNCONNECTED;
+ return SHOUTERR_UNCONNECTED;
}
int shout_set_host(shout_t *self, const char *host)
{
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- if (self->state != SHOUT_STATE_UNCONNECTED)
- return self->error = SHOUTERR_CONNECTED;
+ if (self->state != SHOUT_STATE_UNCONNECTED)
+ return self->error = SHOUTERR_CONNECTED;
- if (self->host)
- free(self->host);
+ if (self->host)
+ free(self->host);
- if (!(self->host = _shout_util_strdup(host)))
- return self->error = SHOUTERR_MALLOC;
+ if ( !(self->host = _shout_util_strdup(host)) )
+ return self->error = SHOUTERR_MALLOC;
- return self->error = SHOUTERR_SUCCESS;
+ return self->error = SHOUTERR_SUCCESS;
}
const char *shout_get_host(shout_t *self)
{
- if (!self)
- return NULL;
+ if (!self)
+ return NULL;
- return self->host;
+ return self->host;
}
int shout_set_port(shout_t *self, unsigned short port)
{
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- if (self->state != SHOUT_STATE_UNCONNECTED)
- return self->error = SHOUTERR_CONNECTED;
+ if (self->state != SHOUT_STATE_UNCONNECTED)
+ return self->error = SHOUTERR_CONNECTED;
- self->port = port;
+ self->port = port;
- return self->error = SHOUTERR_SUCCESS;
+ return self->error = SHOUTERR_SUCCESS;
}
unsigned short shout_get_port(shout_t *self)
{
- if (!self)
- return 0;
+ if (!self)
+ return 0;
- return self->port;
+ return self->port;
}
int shout_set_password(shout_t *self, const char *password)
{
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- if (self->state != SHOUT_STATE_UNCONNECTED)
- return self->error = SHOUTERR_CONNECTED;
+ if (self->state != SHOUT_STATE_UNCONNECTED)
+ return self->error = SHOUTERR_CONNECTED;
- if (self->password)
- free (self->password);
+ if (self->password)
+ free(self->password);
- if (!(self->password = _shout_util_strdup(password)))
- return self->error = SHOUTERR_MALLOC;
+ if ( !(self->password = _shout_util_strdup(password)) )
+ return self->error = SHOUTERR_MALLOC;
- return self->error = SHOUTERR_SUCCESS;
+ return self->error = SHOUTERR_SUCCESS;
}
const char* shout_get_password(shout_t *self)
{
- if (!self)
- return NULL;
+ if (!self)
+ return NULL;
- return self->password;
+ return self->password;
}
int shout_set_mount(shout_t *self, const char *mount)
{
- size_t len;
+ size_t len;
- if (!self || !mount)
- return SHOUTERR_INSANE;
+ if (!self || !mount)
+ return SHOUTERR_INSANE;
- if (self->state != SHOUT_STATE_UNCONNECTED)
- return self->error = SHOUTERR_CONNECTED;
-
- if (self->mount)
- free(self->mount);
+ if (self->state != SHOUT_STATE_UNCONNECTED)
+ return self->error = SHOUTERR_CONNECTED;
+
+ if (self->mount)
+ free(self->mount);
- len = strlen (mount) + 1;
- if (mount[0] != '/')
- len++;
+ len = strlen(mount) + 1;
+ if (mount[0] != '/')
+ len++;
- if (!(self->mount = malloc(len)))
- return self->error = SHOUTERR_MALLOC;
+ if ( !(self->mount = malloc(len)) )
+ return self->error = SHOUTERR_MALLOC;
- snprintf (self->mount, len, "%s%s", mount[0] == '/' ? "" : "/", mount);
+ snprintf(self->mount, len, "%s%s", mount[0] == '/' ? "" : "/", mount);
- return self->error = SHOUTERR_SUCCESS;
+ return self->error = SHOUTERR_SUCCESS;
}
const char *shout_get_mount(shout_t *self)
{
- if (!self)
- return NULL;
+ if (!self)
+ return NULL;
- return self->mount;
+ return self->mount;
}
int shout_set_name(shout_t *self, const char *name)
{
- return shout_set_meta(self, "name", name);
+ return shout_set_meta(self, "name", name);
}
const char *shout_get_name(shout_t *self)
{
- return shout_get_meta(self, "name");
+ return shout_get_meta(self, "name");
}
int shout_set_url(shout_t *self, const char *url)
{
- return shout_set_meta(self, "url", url);
+ return shout_set_meta(self, "url", url);
}
const char *shout_get_url(shout_t *self)
{
- return shout_get_meta(self, "url");
+ return shout_get_meta(self, "url");
}
int shout_set_genre(shout_t *self, const char *genre)
{
- return shout_set_meta(self, "genre", genre);
+ return shout_set_meta(self, "genre", genre);
}
const char *shout_get_genre(shout_t *self)
{
- return shout_get_meta(self, "genre");
+ return shout_get_meta(self, "genre");
}
int shout_set_agent(shout_t *self, const char *agent)
{
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- if (self->state != SHOUT_STATE_UNCONNECTED)
- return self->error = SHOUTERR_CONNECTED;
+ if (self->state != SHOUT_STATE_UNCONNECTED)
+ return self->error = SHOUTERR_CONNECTED;
- if (self->useragent)
- free(self->useragent);
+ if (self->useragent)
+ free(self->useragent);
- if (! (self->useragent = _shout_util_strdup (agent)))
- return self->error = SHOUTERR_MALLOC;
+ if ( !(self->useragent = _shout_util_strdup(agent)) )
+ return self->error = SHOUTERR_MALLOC;
- return self->error = SHOUTERR_SUCCESS;
+ return self->error = SHOUTERR_SUCCESS;
}
const char *shout_get_agent(shout_t *self)
{
- if (!self)
- return NULL;
+ if (!self)
+ return NULL;
- return self->useragent;
+ return self->useragent;
}
int shout_set_user(shout_t *self, const char *username)
{
- if (!self)
- return SHOUTERR_INSANE;
+ if (!self)
+ return SHOUTERR_INSANE;
- if (self->state != SHOUT_STATE_UNCONNECTED)
- return self->error = SHOUTERR_CONNECTED;
+ if (self->state != SHOUT_STATE_UNCONNECTED)
+ return self->error = SHOUTERR_CONNECTED;
- if (self->user)
- free(self->user);
+ if (self->user)
+ free(self->user);
- if (! (self->user = _shout_util_strdup (username)))
- return self->error = SHOUTERR_MALLOC;
+ if ( !(self->user = _shout_util_strdup(username)) )
+ return self->error = SHOUTERR_MALLOC;
- return self->error = SHOUTERR_SUCCESS;
+ return self->error = SHOUTERR_SUCCESS;
}