aboutsummaryrefslogtreecommitdiffstats
path: root/src/command.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-10-03 17:03:53 -0700
committerEric Wong <normalperson@yhbt.net>2008-10-03 17:17:35 -0700
commit8d9a77bfcb2e37728f1a683a74d266d145aff14c (patch)
treebfb97602de8af33b7ef2a290ed59b250a08a7e7d /src/command.c
parent41a44f79ee1e559257fb6b2c88e1eb140fe657bf (diff)
downloadmpd-8d9a77bfcb2e37728f1a683a74d266d145aff14c.tar.gz
mpd-8d9a77bfcb2e37728f1a683a74d266d145aff14c.tar.xz
mpd-8d9a77bfcb2e37728f1a683a74d266d145aff14c.zip
directory: simplify list update handling logic
Now the "update" command can be issued multiple times regardless of whether the client is in list mode or not. We serialize the update tasks to prevent updates from trampling over each other and will spawn another update task once the current one is finished updating and reaped. Right now we cap the queue size to 32 which is probably enough (I bet most people usually run update with no argument anyways); but we can make it grow/shrink dynamically if needed. There'll still be a hard-coded limit to prevent DoS attacks, though.
Diffstat (limited to 'src/command.c')
-rw-r--r--src/command.c44
1 files changed, 7 insertions, 37 deletions
diff --git a/src/command.c b/src/command.c
index 70bfa78b5..07f422720 100644
--- a/src/command.c
+++ b/src/command.c
@@ -813,47 +813,17 @@ static int print_update_result(int fd, int ret)
return -1;
}
-static int listHandleUpdate(int fd,
- mpd_unused int *permission,
- mpd_unused int argc,
- char *argv[],
- struct strnode *cmdnode, CommandEntry * cmd)
-{
- static char **pathv;
- static int pathc;
- CommandEntry *nextCmd = NULL;
- struct strnode *next = cmdnode->next;
- int last = pathc++;
-
- pathv = xrealloc(pathv, pathc * sizeof(char *));
- pathv[last] = sanitizePathDup(argc == 2 ? argv[1] : "");
-
- if (next)
- nextCmd = getCommandEntryFromString(next->data, permission);
-
- if (cmd != nextCmd) {
- int ret = print_update_result(fd, updateInit(pathc, pathv));
- if (pathc) {
- assert(pathv);
- free(pathv);
- pathv = NULL;
- pathc = 0;
- }
- return ret;
- }
-
- return 0;
-}
-
static int handleUpdate(int fd, mpd_unused int *permission,
mpd_unused int argc, char *argv[])
{
- char *pathv[1];
+ char *path = NULL;
assert(argc <= 2);
- if (argc == 2)
- pathv[0] = sanitizePathDup(argv[1]);
- return print_update_result(fd, updateInit(argc - 1, pathv));
+ if (argc == 2 && !(path = sanitizePathDup(argv[1]))) {
+ commandError(fd, ACK_ERROR_ARG, "invalid path");
+ return -1;
+ }
+ return print_update_result(fd, directory_update_init(path));
}
static int handleNext(mpd_unused int fd, mpd_unused int *permission,
@@ -1289,7 +1259,7 @@ void initCommands(void)
addCommand(COMMAND_PLAYLISTINFO, PERMISSION_READ, 0, 1, handlePlaylistInfo, NULL);
addCommand(COMMAND_FIND, PERMISSION_READ, 2, -1, handleFind, NULL);
addCommand(COMMAND_SEARCH, PERMISSION_READ, 2, -1, handleSearch, NULL);
- addCommand(COMMAND_UPDATE, PERMISSION_ADMIN, 0, 1, handleUpdate, listHandleUpdate);
+ addCommand(COMMAND_UPDATE, PERMISSION_ADMIN, 0, 1, handleUpdate, NULL);
addCommand(COMMAND_NEXT, PERMISSION_CONTROL, 0, 0, handleNext, NULL);
addCommand(COMMAND_PREVIOUS, PERMISSION_CONTROL, 0, 0, handlePrevious, NULL);
addCommand(COMMAND_LISTALL, PERMISSION_READ, 0, 1, handleListAll, NULL);