aboutsummaryrefslogtreecommitdiffstats
path: root/src/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/command.c')
-rw-r--r--src/command.c393
1 files changed, 16 insertions, 377 deletions
diff --git a/src/command.c b/src/command.c
index 86d216a75..7bb49447d 100644
--- a/src/command.c
+++ b/src/command.c
@@ -19,6 +19,8 @@
#include "config.h"
#include "command.h"
+#include "DatabaseCommands.hxx"
+#include "CommandError.h"
#include "protocol/argparser.h"
#include "protocol/result.h"
#include "player_control.h"
@@ -28,6 +30,7 @@
#include "playlist_queue.h"
#include "playlist_error.h"
#include "queue_print.h"
+#include "time_print.h"
#include "ls.h"
#include "uri.h"
#include "decoder_print.h"
@@ -44,9 +47,6 @@
#include "output_print.h"
#include "locate.h"
#include "dbUtils.h"
-#include "db_error.h"
-#include "db_print.h"
-#include "db_selection.h"
#include "db_lock.h"
#include "tag.h"
#include "client.h"
@@ -110,135 +110,17 @@ struct command {
enum command_return (*handler)(struct client *client, int argc, char **argv);
};
-static enum command_return
-print_playlist_result(struct client *client,
- enum playlist_result result)
-{
- switch (result) {
- case PLAYLIST_RESULT_SUCCESS:
- return COMMAND_RETURN_OK;
-
- case PLAYLIST_RESULT_ERRNO:
- command_error(client, ACK_ERROR_SYSTEM, "%s",
- g_strerror(errno));
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_DENIED:
- command_error(client, ACK_ERROR_PERMISSION, "Access denied");
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_NO_SUCH_SONG:
- command_error(client, ACK_ERROR_NO_EXIST, "No such song");
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_NO_SUCH_LIST:
- command_error(client, ACK_ERROR_NO_EXIST, "No such playlist");
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_LIST_EXISTS:
- command_error(client, ACK_ERROR_EXIST,
- "Playlist already exists");
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_BAD_NAME:
- command_error(client, ACK_ERROR_ARG,
- "playlist name is invalid: "
- "playlist names may not contain slashes,"
- " newlines or carriage returns");
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_BAD_RANGE:
- command_error(client, ACK_ERROR_ARG, "Bad song index");
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_NOT_PLAYING:
- command_error(client, ACK_ERROR_PLAYER_SYNC, "Not playing");
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_TOO_LARGE:
- command_error(client, ACK_ERROR_PLAYLIST_MAX,
- "playlist is at the max size");
- return COMMAND_RETURN_ERROR;
-
- case PLAYLIST_RESULT_DISABLED:
- command_error(client, ACK_ERROR_UNKNOWN,
- "stored playlist support is disabled");
- return COMMAND_RETURN_ERROR;
- }
-
- assert(0);
- return COMMAND_RETURN_ERROR;
-}
-
-/**
- * Send the GError to the client and free the GError.
- */
-static enum command_return
-print_error(struct client *client, GError *error)
-{
- assert(client != NULL);
- assert(error != NULL);
-
- g_warning("%s", error->message);
-
- if (error->domain == playlist_quark()) {
- enum playlist_result result = error->code;
- g_error_free(error);
- return print_playlist_result(client, result);
- } else if (error->domain == ack_quark()) {
- command_error(client, error->code, "%s", error->message);
- g_error_free(error);
- return COMMAND_RETURN_ERROR;
- } else if (error->domain == db_quark()) {
- switch ((enum db_error)error->code) {
- case DB_DISABLED:
- command_error(client, ACK_ERROR_NO_EXIST, "%s",
- error->message);
- g_error_free(error);
- return COMMAND_RETURN_ERROR;
-
- case DB_NOT_FOUND:
- g_error_free(error);
- command_error(client, ACK_ERROR_NO_EXIST, "Not found");
- return COMMAND_RETURN_ERROR;
- }
- } else if (error->domain == g_file_error_quark()) {
- command_error(client, ACK_ERROR_SYSTEM, "%s",
- g_strerror(error->code));
- g_error_free(error);
- return COMMAND_RETURN_ERROR;
- }
-
- g_error_free(error);
- command_error(client, ACK_ERROR_UNKNOWN, "error");
- return COMMAND_RETURN_ERROR;
-}
-
static void
print_spl_list(struct client *client, GPtrArray *list)
{
for (unsigned i = 0; i < list->len; ++i) {
struct stored_playlist_info *playlist =
g_ptr_array_index(list, i);
- time_t t;
-#ifndef WIN32
- struct tm tm;
-#endif
- char timestamp[32];
client_printf(client, "playlist: %s\n", playlist->name);
- t = playlist->mtime;
- strftime(timestamp, sizeof(timestamp),
-#ifdef G_OS_WIN32
- "%Y-%m-%dT%H:%M:%SZ",
- gmtime(&t)
-#else
- "%FT%TZ",
- gmtime_r(&t, &tm)
-#endif
- );
- client_printf(client, "Last-Modified: %s\n", timestamp);
+ if (playlist->mtime > 0)
+ time_print(client, "Last-Modified", playlist->mtime);
}
}
@@ -685,12 +567,9 @@ handle_lsinfo(struct client *client, int argc, char *argv[])
return COMMAND_RETURN_OK;
}
- struct db_selection selection;
- db_selection_init(&selection, uri, false);
-
- GError *error = NULL;
- if (!db_selection_print(client, &selection, true, &error))
- return print_error(client, error);
+ enum command_return result = handle_lsinfo2(client, argc, argv);
+ if (result != COMMAND_RETURN_OK)
+ return result;
if (isRootDirectory(uri)) {
GPtrArray *list = spl_list(NULL);
@@ -782,194 +661,34 @@ handle_playlistid(struct client *client, int argc, char *argv[])
}
static enum command_return
-handle_find(struct client *client, int argc, char *argv[])
-{
- struct locate_item_list *list =
- locate_item_list_parse(argv + 1, argc - 1);
-
- if (list == NULL || list->length == 0) {
- if (list != NULL)
- locate_item_list_free(list);
-
- command_error(client, ACK_ERROR_ARG, "incorrect arguments");
- return COMMAND_RETURN_ERROR;
- }
-
- GError *error = NULL;
- enum command_return ret = findSongsIn(client, "", list, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
-
- locate_item_list_free(list);
-
- return ret;
-}
-
-static enum command_return
-handle_findadd(struct client *client, int argc, char *argv[])
-{
- struct locate_item_list *list =
- locate_item_list_parse(argv + 1, argc - 1);
- if (list == NULL || list->length == 0) {
- if (list != NULL)
- locate_item_list_free(list);
-
- command_error(client, ACK_ERROR_ARG, "incorrect arguments");
- return COMMAND_RETURN_ERROR;
- }
-
- GError *error = NULL;
- enum command_return ret =
- findAddIn(client->player_control, "", list, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
-
- locate_item_list_free(list);
-
- return ret;
-}
-
-static enum command_return
-handle_search(struct client *client, int argc, char *argv[])
-{
- struct locate_item_list *list =
- locate_item_list_parse(argv + 1, argc - 1);
-
- if (list == NULL || list->length == 0) {
- if (list != NULL)
- locate_item_list_free(list);
-
- command_error(client, ACK_ERROR_ARG, "incorrect arguments");
- return COMMAND_RETURN_ERROR;
- }
-
- GError *error = NULL;
- enum command_return ret = searchForSongsIn(client, "", list, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
-
- locate_item_list_free(list);
-
- return ret;
-}
-
-static enum command_return
-handle_searchadd(struct client *client, int argc, char *argv[])
-{
- struct locate_item_list *list =
- locate_item_list_parse(argv + 1, argc - 1);
-
- if (list == NULL || list->length == 0) {
- if (list != NULL)
- locate_item_list_free(list);
-
- command_error(client, ACK_ERROR_ARG, "incorrect arguments");
- return COMMAND_RETURN_ERROR;
- }
-
- GError *error = NULL;
- enum command_return ret = search_add_songs(client->player_control,
- "", list, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
-
- locate_item_list_free(list);
-
- return ret;
-}
-
-static enum command_return
-handle_searchaddpl(struct client *client, int argc, char *argv[])
+handle_playlist_match(struct client *client, int argc, char *argv[],
+ bool fold_case)
{
- const char *playlist = argv[1];
-
struct locate_item_list *list =
- locate_item_list_parse(argv + 2, argc - 2);
-
- if (list == NULL || list->length == 0) {
- if (list != NULL)
- locate_item_list_free(list);
+ locate_item_list_parse(argv + 1, argc - 1, fold_case);
+ if (list == NULL) {
command_error(client, ACK_ERROR_ARG, "incorrect arguments");
return COMMAND_RETURN_ERROR;
}
- GError *error = NULL;
- enum command_return ret =
- search_add_to_playlist("", playlist, list, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
-
- locate_item_list_free(list);
-
- return ret;
-}
-
-static enum command_return
-handle_count(struct client *client, int argc, char *argv[])
-{
- struct locate_item_list *list =
- locate_item_list_parse(argv + 1, argc - 1);
-
- if (list == NULL || list->length == 0) {
- if (list != NULL)
- locate_item_list_free(list);
-
- command_error(client, ACK_ERROR_ARG, "incorrect arguments");
- return COMMAND_RETURN_ERROR;
- }
-
- GError *error = NULL;
- enum command_return ret =
- searchStatsForSongsIn(client, "", list, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
+ playlist_print_find(client, &g_playlist, list);
locate_item_list_free(list);
- return ret;
+ return COMMAND_RETURN_OK;
}
static enum command_return
handle_playlistfind(struct client *client, int argc, char *argv[])
{
- struct locate_item_list *list =
- locate_item_list_parse(argv + 1, argc - 1);
-
- if (list == NULL || list->length == 0) {
- if (list != NULL)
- locate_item_list_free(list);
-
- command_error(client, ACK_ERROR_ARG, "incorrect arguments");
- return COMMAND_RETURN_ERROR;
- }
-
- playlist_print_find(client, &g_playlist, list);
-
- locate_item_list_free(list);
-
- return COMMAND_RETURN_OK;
+ return handle_playlist_match(client, argc, argv, false);
}
static enum command_return
handle_playlistsearch(struct client *client, int argc, char *argv[])
{
- struct locate_item_list *list =
- locate_item_list_parse(argv + 1, argc - 1);
-
- if (list == NULL || list->length == 0) {
- if (list != NULL)
- locate_item_list_free(list);
-
- command_error(client, ACK_ERROR_ARG, "incorrect arguments");
- return COMMAND_RETURN_ERROR;
- }
-
- playlist_print_search(client, &g_playlist, list);
-
- locate_item_list_free(list);
-
- return COMMAND_RETURN_OK;
+ return handle_playlist_match(client, argc, argv, true);
}
static enum command_return
@@ -1149,20 +868,6 @@ handle_prioid(struct client *client, int argc, char *argv[])
}
static enum command_return
-handle_listall(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
-{
- const char *directory = "";
-
- if (argc == 2)
- directory = argv[1];
-
- GError *error = NULL;
- return printAllIn(client, directory, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
-}
-
-static enum command_return
handle_setvol(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
{
unsigned level;
@@ -1246,58 +951,6 @@ handle_clearerror(G_GNUC_UNUSED struct client *client,
}
static enum command_return
-handle_list(struct client *client, int argc, char *argv[])
-{
- struct locate_item_list *conditionals;
- int tagType = locate_parse_type(argv[1]);
-
- if (tagType < 0) {
- command_error(client, ACK_ERROR_ARG, "\"%s\" is not known", argv[1]);
- return COMMAND_RETURN_ERROR;
- }
-
- if (tagType == LOCATE_TAG_ANY_TYPE) {
- command_error(client, ACK_ERROR_ARG,
- "\"any\" is not a valid return tag type");
- return COMMAND_RETURN_ERROR;
- }
-
- /* for compatibility with < 0.12.0 */
- if (argc == 3) {
- if (tagType != TAG_ALBUM) {
- command_error(client, ACK_ERROR_ARG,
- "should be \"%s\" for 3 arguments",
- tag_item_names[TAG_ALBUM]);
- return COMMAND_RETURN_ERROR;
- }
-
- locate_item_list_parse(argv + 1, argc - 1);
-
- conditionals = locate_item_list_new(1);
- conditionals->items[0].tag = TAG_ARTIST;
- conditionals->items[0].needle = g_strdup(argv[2]);
- } else {
- conditionals =
- locate_item_list_parse(argv + 2, argc - 2);
- if (conditionals == NULL) {
- command_error(client, ACK_ERROR_ARG,
- "not able to parse args");
- return COMMAND_RETURN_ERROR;
- }
- }
-
- GError *error = NULL;
- enum command_return ret =
- listAllUniqueTags(client, tagType, conditionals, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
-
- locate_item_list_free(conditionals);
-
- return ret;
-}
-
-static enum command_return
handle_move(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
{
unsigned start, end;
@@ -1407,20 +1060,6 @@ handle_seekcur(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
}
static enum command_return
-handle_listallinfo(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
-{
- const char *directory = "";
-
- if (argc == 2)
- directory = argv[1];
-
- GError *error = NULL;
- return printInfoForAllIn(client, directory, &error)
- ? COMMAND_RETURN_OK
- : print_error(client, error);
-}
-
-static enum command_return
handle_ping(G_GNUC_UNUSED struct client *client,
G_GNUC_UNUSED int argc, G_GNUC_UNUSED char *argv[])
{