Fix a few minor misspellings.
[libmpdclient.git] / src / idle.c
blob96b28e817ff9bebe2ef6af2bcbabb62ec6ff2775
1 /* libmpdclient
2 (c) 2003-2009 The Music Player Daemon Project
3 This project's homepage is: http://www.musicpd.org
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 - Neither the name of the Music Player Daemon nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <mpd/idle.h>
34 #include <mpd/send.h>
35 #include <mpd/connection.h>
36 #include <mpd/pair.h>
37 #include <mpd/recv.h>
38 #include <mpd/response.h>
39 #include "internal.h"
40 #include "isend.h"
41 #include "run.h"
43 #include <string.h>
45 static const char *const idle_names[] = {
46 "database",
47 "stored_playlist",
48 "playlist",
49 "player",
50 "mixer",
51 "output",
52 "options",
53 "update",
54 NULL
57 const char *
58 mpd_idle_name(enum mpd_idle idle)
60 for (unsigned i = 0; idle_names[i] != NULL; ++i)
61 if (idle == (enum mpd_idle)(1 << i))
62 return idle_names[i];
64 return NULL;
67 enum mpd_idle
68 mpd_idle_name_parse(const char *name)
70 assert(name != NULL);
72 for (unsigned i = 0; idle_names[i] != NULL; ++i)
73 if (strcmp(name, idle_names[i]) == 0)
74 return 1 << i;
76 return 0;
79 enum mpd_idle
80 mpd_idle_parse_pair(const struct mpd_pair *pair)
82 assert(pair != NULL);
84 if (strcmp(pair->name, "changed") != 0)
85 return 0;
87 return mpd_idle_name_parse(pair->value);
90 enum mpd_idle
91 mpd_recv_idle(struct mpd_connection *connection)
93 enum mpd_idle flags = 0;
94 struct mpd_pair *pair;
95 struct timeval old_timeout;
97 assert(connection != NULL);
99 /* make sure that the output buffer is empty before we turn
100 off the timeout - this is important because we want to
101 detect a send failure more quickly */
102 if (!mpd_flush(connection))
103 return 0;
105 /* temporarily disable the connection timeout */
106 old_timeout = connection->timeout;
107 connection->timeout = (struct timeval){
108 .tv_sec = 0,
109 .tv_usec = 0,
112 while ((pair = mpd_recv_pair(connection)) != NULL) {
113 flags |= mpd_idle_parse_pair(pair);
115 mpd_return_pair(connection, pair);
118 /* re-enable timeout */
119 connection->timeout = old_timeout;
121 return flags;
124 bool
125 mpd_send_idle(struct mpd_connection *connection)
127 return mpd_send_command(connection, "idle", NULL);
130 bool
131 mpd_send_idle_mask(struct mpd_connection *connection, enum mpd_idle mask)
133 /* this buffer is large enough even for the full mask */
134 char buffer[128] = "idle";
136 assert(mask != 0);
138 if (mpd_error_is_defined(&connection->error))
139 return false;
141 for (unsigned i = 0; idle_names[i] != NULL; ++i) {
142 if (mask & (1 << i)) {
143 mask &= ~(1 << i);
144 strcat(buffer, " ");
145 strcat(buffer, idle_names[i]);
149 if (mask != 0) {
150 /* the client expects that all flags are supported,
151 because he might block forever if an event is not
152 delivered as expected */
153 mpd_error_code(&connection->error, MPD_ERROR_ARGUMENT);
154 mpd_error_printf(&connection->error,
155 "Unsupported idle flags: 0x%x", mask);
156 return false;
159 return mpd_send_command(connection, buffer, NULL);
162 bool
163 mpd_send_noidle(struct mpd_connection *connection)
165 return mpd_send_command(connection, "noidle", NULL);
168 enum mpd_idle
169 mpd_run_idle(struct mpd_connection *connection)
171 enum mpd_idle flags;
173 if (!mpd_run_check(connection) || !mpd_send_idle(connection))
174 return 0;
176 flags = mpd_recv_idle(connection);
177 if (!mpd_response_finish(connection))
178 return 0;
180 return flags;
183 enum mpd_idle
184 mpd_run_idle_mask(struct mpd_connection *connection, enum mpd_idle mask)
186 enum mpd_idle flags;
188 if (!mpd_run_check(connection) ||
189 !mpd_send_idle_mask(connection, mask))
190 return 0;
192 flags = mpd_recv_idle(connection);
193 if (!mpd_response_finish(connection))
194 return 0;
196 return flags;