Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

settings: expose connection settings

To determine connection settings.  Move code from
mpd_connection_new().
  • Loading branch information...
commit 8b280fa9158cceb8d7f824eafc48c01dc7e28e8a 1 parent ab7c3db
@MaxKellermann MaxKellermann authored
View
2  Makefile.am
@@ -33,6 +33,7 @@ mpdinclude_HEADERS = \
include/mpd/search.h \
include/mpd/song.h \
include/mpd/sticker.h \
+ include/mpd/settings.h \
include/mpd/version.h
AM_CPPFLAGS += -I$(srcdir)/include -Iinclude
@@ -82,6 +83,7 @@ src_libmpdclient_la_SOURCES = \
src/sync.c src/sync.h \
src/tag.c \
src/sticker.c \
+ src/settings.c \
src/uri.h
src_libmpdclient_la_LDFLAGS = -version-info @LIBMPDCLIENT_LIBTOOL_VERSION@ \
View
1  NEWS
@@ -3,6 +3,7 @@ libmpdclient 2.4 (2010/??/??)
* resolver: fix IPv4/IPv6 on the loopback device
* player: support the command "clearerror"
* connection: add function mpd_connection_get_server_error_location()
+* settings: expose connection settings
libmpdclient 2.3 (2010/05/25)
View
1  include/mpd/client.h
@@ -64,6 +64,7 @@
#include <mpd/response.h>
#include <mpd/search.h>
#include <mpd/send.h>
+#include <mpd/settings.h>
#include <mpd/song.h>
#include <mpd/stats.h>
#include <mpd/status.h>
View
7 include/mpd/connection.h
@@ -125,6 +125,13 @@ mpd_connection_new_async(struct mpd_async *async, const char *welcome);
void mpd_connection_free(struct mpd_connection *connection);
/**
+ * Returns the settings which were used to connect to the server. May
+ * be NULL if the settings are not known.
+ */
+const struct mpd_settings *
+mpd_connection_get_settings(const struct mpd_connection *connection);
+
+/**
* Sets the timeout for synchronous operations. If the MPD server
* does not send a response during this time span, the operation is
* aborted by libmpdclient.
View
108 include/mpd/settings.h
@@ -0,0 +1,108 @@
+/* libmpdclient
+ (c) 2003-2010 The Music Player Daemon Project
+ This project's homepage is: http://www.musicpd.org
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*! \file
+ * \brief MPD client library
+ *
+ * Library to determine connection settings prior to calling
+ * mpd_connection_new().
+ *
+ * Do not include this header directly. Use mpd/client.h instead.
+ */
+
+#ifndef MPD_SETTINGS_H
+#define MPD_SETTINGS_H
+
+#include <stdbool.h>
+
+/**
+ * An object which describes configurable connection settings.
+ */
+struct mpd_settings;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Creates a new #mpd_settings object. The values which are not
+ * passed by the caller are taken from environment variables.
+ *
+ * @param host the server's host name, IP address or Unix socket path.
+ * NULL is allowed here, which will connect to the default host
+ * (using the MPD_HOST environment variable if present).
+ * @param port the TCP port to connect to, 0 for default port (using
+ * the MPD_PORT environment variable if present). If "host" is a Unix
+ * socket path, this parameter is ignored.
+ * @param timeout_ms the timeout in milliseconds, 0 for the default
+ * timeout (the environment variable MPD_TIMEOUT may specify a timeout
+ * in seconds)
+ * @param reserved reserved for future use, pass NULL
+ * @param password the password, or NULL to use the default (MPD_HOST
+ * before "@")
+ * @return a #mpd_settings object or NULL if out of memory
+ */
+struct mpd_settings *
+mpd_settings_new(const char *host, unsigned port, unsigned timeout_ms,
+ const char *reserved, const char *password);
+
+/**
+ * Releases a #mpd_settings object.
+ */
+void
+mpd_settings_free(struct mpd_settings *settings);
+
+/**
+ * Returns the host name (without password/port), or NULL if unknown.
+ */
+const char *
+mpd_settings_get_host(const struct mpd_settings *settings);
+
+/**
+ * Returns the port number, or 0 if not applicable.
+ */
+unsigned
+mpd_settings_get_port(const struct mpd_settings *settings);
+
+/**
+ * Returns the timeout in milliseconds, or 0 if unknown.
+ */
+unsigned
+mpd_settings_get_timeout_ms(const struct mpd_settings *settings);
+
+/**
+ * Returns the password, or NULL if none was configured.
+ */
+const char *
+mpd_settings_get_password(const struct mpd_settings *settings);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
View
9 libmpdclient.ld
@@ -23,6 +23,7 @@ global:
mpd_connection_new;
mpd_connection_new_async;
mpd_connection_free;
+ mpd_connection_get_settings;
mpd_connection_set_timeout;
mpd_connection_get_fd;
mpd_connection_get_async;
@@ -320,6 +321,14 @@ global:
mpd_recv_sticker;
mpd_return_sticker;
+ /* mpd/settings.h */
+ mpd_settings_new;
+ mpd_settings_free;
+ mpd_settings_get_host;
+ mpd_settings_get_port;
+ mpd_settings_get_timeout_ms;
+ mpd_settings_get_password;
+
local:
*;
};
View
177 src/connection.c
@@ -31,6 +31,7 @@
*/
#include <mpd/connection.h>
+#include <mpd/settings.h>
#include <mpd/async.h>
#include <mpd/parser.h>
#include <mpd/password.h>
@@ -94,126 +95,25 @@ mpd_connection_sync_error(struct mpd_connection *connection)
}
}
-/**
- * Parses the password from the host specification in the form
- * "password@hostname".
- *
- * @param host_p a pointer to the "host" variable, which may be
- * modified by this function
- * @return an allocated password string, or NULL if there was no
- * password
- */
-static const char *
-mpd_parse_host_password(const char *host, char **password_r)
-{
- const char *at;
- char *password;
-
- assert(password_r != NULL);
- assert(*password_r == NULL);
-
- if (host == NULL)
- return host;
-
- at = strchr(host, '@');
- if (at == NULL)
- return host;
-
- password = malloc(at - host + 1);
- if (password != NULL) {
- /* silently ignoring out-of-memory */
- memcpy(password, host, at - host);
- password[at - host] = 0;
- *password_r = password;
- }
-
- return at + 1;
-}
-
-/**
- * Parses the host specification. If not specified, it attempts to
- * load it from the environment variable MPD_HOST.
- */
-static const char *
-mpd_check_host(const char *host, char **password_r)
-{
- assert(password_r != NULL);
- assert(*password_r == NULL);
-
- if (host == NULL)
- host = getenv("MPD_HOST");
-
- if (host != NULL)
- host = mpd_parse_host_password(host, password_r);
-
- return host;
-}
-
-/**
- * Parses the port specification. If not specified (0), it attempts
- * to load it from the environment variable MPD_PORT.
- */
-static unsigned
-mpd_check_port(unsigned port)
-{
- if (port == 0) {
- const char *env_port = getenv("MPD_PORT");
- if (env_port != NULL)
- port = atoi(env_port);
- }
-
- return port;
-}
-
-static int
-mpd_connect(const char *host, unsigned port, const struct timeval *timeout,
- struct mpd_error_info *error)
+struct mpd_connection *
+mpd_connection_new(const char *host, unsigned port, unsigned timeout_ms)
{
-#ifdef DEFAULT_SOCKET
- if (host == NULL && port == 0) {
- int fd = mpd_socket_connect(DEFAULT_SOCKET, 0, timeout, error);
- if (fd >= 0)
- return fd;
-
- mpd_error_clear(error);
- }
-#endif
-
- if (host == NULL)
- host = DEFAULT_HOST;
-
- if (port == 0)
- port = DEFAULT_PORT;
-
- return mpd_socket_connect(host, port, timeout, error);
-}
+ struct mpd_settings *settings =
+ mpd_settings_new(host, port, timeout_ms, NULL, NULL);
+ if (settings == NULL)
+ return NULL;
-static unsigned
-mpd_default_timeout_ms(void)
-{
- const char *timeout_string = getenv("MPD_TIMEOUT");
- if (timeout_string != NULL) {
- int timeout_s = atoi(timeout_string);
- if (timeout_s > 0)
- return timeout_s * 1000;
+ struct mpd_connection *connection = malloc(sizeof(*connection));
+ if (connection == NULL) {
+ mpd_settings_free(settings);
+ return NULL;
}
- /* 30s is the default */
- return 30000;
-}
+ connection->settings = settings;
-struct mpd_connection *
-mpd_connection_new(const char *host, unsigned port, unsigned timeout_ms)
-{
- struct mpd_connection *connection = malloc(sizeof(*connection));
bool success;
int fd;
const char *line;
- char *password = NULL;
-
-
- if (connection == NULL)
- return NULL;
mpd_error_init(&connection->error);
connection->async = NULL;
@@ -226,23 +126,35 @@ mpd_connection_new(const char *host, unsigned port, unsigned timeout_ms)
if (!mpd_socket_global_init(&connection->error))
return connection;
- if (timeout_ms == 0)
- timeout_ms = mpd_default_timeout_ms();
-
- mpd_connection_set_timeout(connection, timeout_ms);
+ mpd_connection_set_timeout(connection,
+ mpd_settings_get_timeout_ms(settings));
- host = mpd_check_host(host, &password);
- port = mpd_check_port(port);
-
- fd = mpd_connect(host, port, &connection->timeout, &connection->error);
+ host = mpd_settings_get_host(settings);
+ fd = mpd_socket_connect(host, mpd_settings_get_port(settings),
+ &connection->timeout, &connection->error);
if (fd < 0) {
- free(password);
- return connection;
+#if defined(DEFAULT_SOCKET) && defined(ENABLE_TCP)
+ if (host == NULL || strcmp(host, DEFAULT_SOCKET) == 0) {
+ /* special case: try the default host if the
+ default socket failed */
+ mpd_settings_free(settings);
+ settings = mpd_settings_new(DEFAULT_HOST, DEFAULT_PORT,
+ timeout_ms, NULL, NULL);
+ connection->settings = settings;
+
+ mpd_error_clear(&connection->error);
+ fd = mpd_socket_connect(DEFAULT_HOST, DEFAULT_PORT,
+ &connection->timeout,
+ &connection->error);
+ }
+#endif
+
+ if (fd < 0)
+ return connection;
}
connection->async = mpd_async_new(fd);
if (connection->async == NULL) {
- free(password);
mpd_socket_close(fd);
mpd_error_code(&connection->error, MPD_ERROR_OOM);
return connection;
@@ -250,24 +162,22 @@ mpd_connection_new(const char *host, unsigned port, unsigned timeout_ms)
connection->parser = mpd_parser_new();
if (connection->parser == NULL) {
- free(password);
mpd_error_code(&connection->error, MPD_ERROR_OOM);
return connection;
}
line = mpd_sync_recv_line(connection->async, &connection->timeout);
if (line == NULL) {
- free(password);
mpd_connection_sync_error(connection);
return connection;
}
success = mpd_parse_welcome(connection, line);
- if (password != NULL) {
- if (success)
+ if (success) {
+ const char *password = mpd_settings_get_password(settings);
+ if (password != NULL)
mpd_run_password(connection, password);
- free(password);
}
return connection;
@@ -322,9 +232,20 @@ void mpd_connection_free(struct mpd_connection *connection)
mpd_error_deinit(&connection->error);
+ if (connection->settings != NULL)
+ mpd_settings_free(connection->settings);
+
free(connection);
}
+const struct mpd_settings *
+mpd_connection_get_settings(const struct mpd_connection *connection)
+{
+ assert(connection != NULL);
+
+ return connection->settings;
+}
+
void
mpd_connection_set_timeout(struct mpd_connection *connection,
unsigned timeout_ms)
View
5 src/internal.h
@@ -41,6 +41,11 @@
*/
struct mpd_connection {
/**
+ * The connection settings.
+ */
+ struct mpd_settings *settings;
+
+ /**
* The version number received by the MPD server.
*/
unsigned version[3];
View
201 src/settings.c
@@ -0,0 +1,201 @@
+/* libmpdclient
+ (c) 2003-2010 The Music Player Daemon Project
+ This project's homepage is: http://www.musicpd.org
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <mpd/settings.h>
+#include "config.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+struct mpd_settings {
+ char *host;
+
+ unsigned port, timeout_ms;
+
+ char *password;
+};
+
+/**
+ * Parses the password from the host specification in the form
+ * "password@hostname".
+ *
+ * @param host_p a pointer to the "host" variable, which may be
+ * modified by this function
+ * @return an allocated password string, or NULL if there was no
+ * password
+ */
+static const char *
+mpd_parse_host_password(const char *host, char **password_r)
+{
+ const char *at;
+ char *password;
+
+ assert(password_r != NULL);
+ assert(*password_r == NULL);
+
+ if (host == NULL)
+ return host;
+
+ at = strchr(host, '@');
+ if (at == NULL)
+ return host;
+
+ password = malloc(at - host + 1);
+ if (password != NULL) {
+ /* silently ignoring out-of-memory */
+ memcpy(password, host, at - host);
+ password[at - host] = 0;
+ *password_r = password;
+ }
+
+ return at + 1;
+}
+
+/**
+ * Parses the host specification. If not specified, it attempts to
+ * load it from the environment variable MPD_HOST.
+ */
+static const char *
+mpd_check_host(const char *host, char **password_r)
+{
+ assert(password_r != NULL);
+ assert(*password_r == NULL);
+
+ if (host == NULL)
+ host = getenv("MPD_HOST");
+
+ if (host != NULL)
+ host = mpd_parse_host_password(host, password_r);
+
+ return host;
+}
+
+/**
+ * Parses the port specification. If not specified (0), it attempts
+ * to load it from the environment variable MPD_PORT.
+ */
+static unsigned
+mpd_check_port(unsigned port)
+{
+ if (port == 0) {
+ const char *env_port = getenv("MPD_PORT");
+ if (env_port != NULL)
+ port = atoi(env_port);
+ }
+
+ return port;
+}
+
+static unsigned
+mpd_default_timeout_ms(void)
+{
+ const char *timeout_string = getenv("MPD_TIMEOUT");
+ if (timeout_string != NULL) {
+ int timeout_s = atoi(timeout_string);
+ if (timeout_s > 0)
+ return timeout_s * 1000;
+ }
+
+ /* 30s is the default */
+ return 30000;
+}
+
+struct mpd_settings *
+mpd_settings_new(const char *host, unsigned port, unsigned timeout_ms,
+ const char *reserved, const char *password)
+{
+ (void)reserved;
+
+ struct mpd_settings *settings = malloc(sizeof(*settings));
+ if (settings == NULL)
+ return settings;
+
+ settings->password = NULL;
+
+ port = mpd_check_port(port);
+
+ host = mpd_check_host(host, &settings->password);
+ if (settings->password == NULL && password != NULL)
+ settings->password = strdup(password);
+
+ if (host == NULL) {
+#ifdef DEFAULT_SOCKET
+ if (port == 0)
+ /* default to local socket only if no port was
+ explicitly configured */
+ host = DEFAULT_SOCKET;
+ else
+#endif
+ host = DEFAULT_HOST;
+ }
+
+ settings->host = strdup(host);
+
+ settings->timeout_ms = timeout_ms != 0
+ ? timeout_ms
+ : mpd_default_timeout_ms();
+
+ settings->port = host[0] == '/'
+ ? 0 /* no port for local socket */
+ : (port != 0 ? port : DEFAULT_PORT);
+
+ return settings;
+}
+
+void
+mpd_settings_free(struct mpd_settings *settings)
+{
+ free(settings->host);
+ free(settings->password);
+ free(settings);
+}
+
+const char *
+mpd_settings_get_host(const struct mpd_settings *settings)
+{
+ return settings->host;
+}
+
+unsigned
+mpd_settings_get_port(const struct mpd_settings *settings)
+{
+ return settings->port;
+}
+
+unsigned
+mpd_settings_get_timeout_ms(const struct mpd_settings *settings)
+{
+ return settings->timeout_ms;
+}
+
+const char *
+mpd_settings_get_password(const struct mpd_settings *settings)
+{
+ return settings->password;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.