commit 3f437ecbe8d96a90bb3d3ca81c191be2223b4dda
parent 2cbc7f8ae2cc154b3e0642b34c0bac4abb3c5bb0
Author: mtmn <miro@haravara.org>
Date: Sat, 23 May 2026 02:23:23 +0200
mpd: apply findings from fuzzing
Diffstat:
6 files changed, 278 insertions(+), 215 deletions(-)
diff --git a/mpd/BUILD b/mpd/BUILD
@@ -9,13 +9,36 @@ COMMON_COPTS = [
"-O2",
"-fanalyzer",
"-Wshadow",
+ "-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=2",
+ "-fPIE",
+ "-Wformat",
+ "-Werror=format-security",
+ "-Wnull-dereference",
+ "-Wdangling-pointer",
+ "-Wtrampolines",
+ "-Walloca",
+ "-Wcast-align=strict",
+ "-Wdate-time",
+ "-Wfloat-equal",
+ "-Wpointer-arith",
+ "-Wredundant-decls",
+ "-Wswitch-default",
+ "-Wvla",
+ "-Wwrite-strings",
+]
+
+COMMON_LINKOPTS = [
+ "-lmpdclient",
+ "-Wl,-z,relro",
+ "-Wl,-z,now",
]
cc_binary(
name = "mpd_add_to_playlist",
srcs = ["mpd_add_to_playlist.c"],
copts = COMMON_COPTS,
- linkopts = ["-lmpdclient"],
+ linkopts = COMMON_LINKOPTS,
visibility = ["//visibility:public"],
)
@@ -23,7 +46,7 @@ cc_binary(
name = "mpd_add_to_queue",
srcs = ["mpd_add_to_queue.c"],
copts = COMMON_COPTS,
- linkopts = ["-lmpdclient"],
+ linkopts = COMMON_LINKOPTS,
visibility = ["//visibility:public"],
)
@@ -31,7 +54,7 @@ cc_binary(
name = "mpd_update_queue",
srcs = ["mpd_update_queue.c"],
copts = COMMON_COPTS,
- linkopts = ["-lmpdclient"],
+ linkopts = COMMON_LINKOPTS,
visibility = ["//visibility:public"],
)
@@ -39,7 +62,7 @@ cc_binary(
name = "mpd_edit_queue",
srcs = ["mpd_edit_queue.c"],
copts = COMMON_COPTS,
- linkopts = ["-lmpdclient"],
+ linkopts = COMMON_LINKOPTS,
visibility = ["//visibility:public"],
)
@@ -47,7 +70,7 @@ cc_binary(
name = "mpd_update_library",
srcs = ["mpd_update_library.c"],
copts = COMMON_COPTS,
- linkopts = ["-lmpdclient"],
+ linkopts = COMMON_LINKOPTS,
visibility = ["//visibility:public"],
)
diff --git a/mpd/mpd_add_to_playlist.c b/mpd/mpd_add_to_playlist.c
@@ -34,20 +34,23 @@ struct mpd_connection *conn() {
D(printf("%s %s:%u\n", "Connecting to", host, port));
struct mpd_connection *c = mpd_connection_new(host, port, 0);
- enum mpd_error err = mpd_connection_get_error(c);
- if (err != 0) {
- printf("Error code: %u. View error codes here: "
- "https://www.musicpd.org/doc/libmpdclient/error_8h.html\n",
- err);
+ if (c == NULL) {
+ fprintf(stderr, "Failed to create MPD connection object\n");
+ return NULL;
+ }
+
+ if (mpd_connection_get_error(c) != MPD_ERROR_SUCCESS) {
+ fprintf(stderr, "Error connecting to MPD (%s:%u): %s\n", host, port,
+ mpd_connection_get_error_message(c));
mpd_connection_free(c);
- return 0;
+ return NULL;
}
#ifdef PASS
const char *pass = PASS;
if (mpd_run_password(c, pass) == false) {
- printf("%s\n", "Bad password");
+ fprintf(stderr, "Bad password\n");
mpd_connection_free(c);
- return 0;
+ return NULL;
}
#endif
D(printf("%s %s:%u\n", "Connected to", host, port));
@@ -64,7 +67,7 @@ int main(int argc, char *argv[]) {
D(printf("Using playlist: %s\n", playlist));
struct mpd_connection *c = conn();
- if (c == 0)
+ if (c == NULL)
return -1;
struct mpd_song *curr = mpd_run_current_song(c);
diff --git a/mpd/mpd_add_to_queue.c b/mpd/mpd_add_to_queue.c
@@ -1,8 +1,8 @@
#include <mpd/client.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
#include <unistd.h>
// #define DEBUG
@@ -25,7 +25,7 @@ struct mpd_connection *conn() {
if (host == NULL || strlen(host) == 0) {
host = DEFAULT_HOST;
}
-
+
unsigned port = DEFAULT_PORT;
const char *port_str = getenv("MPD_PORT");
if (port_str != NULL && strlen(port_str) > 0) {
@@ -40,15 +40,16 @@ struct mpd_connection *conn() {
enum mpd_error err = mpd_connection_get_error(c);
if (err != 0) {
- fprintf(stderr, "Error connecting to MPD (%s:%u): %s (code: %u)\n",
- host, port, mpd_connection_get_error_message(c), err);
+ fprintf(stderr, "Error connecting to MPD (%s:%u): %s (code: %u)\n", host,
+ port, mpd_connection_get_error_message(c), err);
mpd_connection_free(c);
return NULL;
}
#ifdef PASS
const char *pass = PASS;
if (mpd_run_password(c, pass) == false) {
- fprintf(stderr, "MPD authentication failed: %s\n", mpd_connection_get_error_message(c));
+ fprintf(stderr, "MPD authentication failed: %s\n",
+ mpd_connection_get_error_message(c));
mpd_connection_free(c);
return NULL;
}
@@ -58,7 +59,7 @@ struct mpd_connection *conn() {
int main(int argc, char *argv[]) {
FILE *input = stdin;
-
+
if (argc > 1) {
input = fopen(argv[1], "r");
if (input == NULL) {
@@ -66,12 +67,14 @@ int main(int argc, char *argv[]) {
return 1;
}
} else if (isatty(STDIN_FILENO)) {
- fprintf(stderr, "Reading from stdin... (Press Ctrl+D to finish, or provide a filename as argument)\n");
+ fprintf(stderr, "Reading from stdin... (Press Ctrl+D to finish, or provide "
+ "a filename as argument)\n");
}
struct mpd_connection *c = conn();
if (c == NULL) {
- if (input != stdin) fclose(input);
+ if (input != stdin)
+ fclose(input);
return -1;
}
@@ -91,23 +94,29 @@ int main(int argc, char *argv[]) {
read_bytes--;
}
- if (read_bytes == 0) continue;
- if (line[0] == '#') continue;
+ if (read_bytes == 0)
+ continue;
+ if (line[0] == '#')
+ continue;
if (!mpd_run_add(c, line)) {
- fprintf(stderr, "Failed to add track: %s (Error: %s)\n", line, mpd_connection_get_error_message(c));
+ fprintf(stderr, "Failed to add track: %s (Error: %s)\n", line,
+ mpd_connection_get_error_message(c));
failed_count++;
- if (!mpd_connection_clear_error(c)) break;
+ if (!mpd_connection_clear_error(c))
+ break;
} else {
printf("Added: %s\n", line);
added_count++;
}
}
- printf("\nSummary: Added %d tracks, failed to add %d tracks.\n", added_count, failed_count);
+ printf("\nSummary: Added %d tracks, failed to add %d tracks.\n", added_count,
+ failed_count);
free(line);
- if (input != stdin) fclose(input);
+ if (input != stdin)
+ fclose(input);
mpd_connection_free(c);
return 0;
diff --git a/mpd/mpd_edit_queue.c b/mpd/mpd_edit_queue.c
@@ -6,6 +6,7 @@
#include <unistd.h>
#include <sys/wait.h>
#include <ctype.h>
+#include <fcntl.h>
#define DEFAULT_HOST "localhost"
#define DEFAULT_PORT 6600
@@ -46,31 +47,10 @@ int main() {
struct mpd_connection *c = conn();
if (c == NULL) return 1;
- struct mpd_status *status = mpd_run_status(c);
- if (status == NULL) {
- fprintf(stderr, "Error getting status: %s\n", mpd_connection_get_error_message(c));
- mpd_connection_free(c);
- return 1;
- }
- enum mpd_state state = mpd_status_get_state(status);
- int current_pos = mpd_status_get_song_pos(status);
- int total_queue_len = mpd_status_get_queue_length(status);
- mpd_status_free(status);
-
- char *current_file = NULL;
- if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
- struct mpd_song *song = mpd_run_current_song(c);
- if (song != NULL) {
- current_file = strdup(mpd_song_get_uri(song));
- mpd_song_free(song);
- }
- }
-
char tmp_template[] = "/tmp/mpd_queue_XXXXXX";
int fd = mkstemp(tmp_template);
if (fd == -1) {
perror("mkstemp");
- if (current_file) free(current_file);
mpd_connection_free(c);
return 1;
}
@@ -80,7 +60,6 @@ int main() {
perror("fdopen");
close(fd);
unlink(tmp_template);
- if (current_file) free(current_file);
mpd_connection_free(c);
return 1;
}
@@ -89,7 +68,6 @@ int main() {
fprintf(stderr, "Error sending queue request\n");
fclose(f);
unlink(tmp_template);
- if (current_file) free(current_file);
mpd_connection_free(c);
return 1;
}
@@ -107,7 +85,6 @@ int main() {
if (mpd_connection_get_error(c) != MPD_ERROR_SUCCESS) {
fprintf(stderr, "Error reading queue: %s\n", mpd_connection_get_error_message(c));
unlink(tmp_template);
- if (current_file) free(current_file);
mpd_connection_free(c);
return 1;
}
@@ -120,7 +97,6 @@ int main() {
if (pid == -1) {
perror("fork");
unlink(tmp_template);
- if (current_file) free(current_file);
mpd_connection_free(c);
return 1;
} else if (pid == 0) {
@@ -132,11 +108,19 @@ int main() {
int wstatus;
waitpid(pid, &wstatus, 0);
- f = fopen(tmp_template, "r");
+ /* Re-open temp file with O_NOFOLLOW to prevent symlink attacks */
+ int fd2 = open(tmp_template, O_RDONLY | O_NOFOLLOW);
+ if (fd2 == -1) {
+ perror("open");
+ unlink(tmp_template);
+ mpd_connection_free(c);
+ return 1;
+ }
+ f = fdopen(fd2, "r");
if (f == NULL) {
- perror("fopen");
+ perror("fdopen");
+ close(fd2);
unlink(tmp_template);
- if (current_file) free(current_file);
mpd_connection_free(c);
return 1;
}
@@ -146,6 +130,10 @@ int main() {
char *line = NULL;
size_t len = 0;
ssize_t read_bytes;
+ char *current_file = NULL;
+ enum mpd_state state;
+ int current_pos;
+ int total_queue_len;
int new_pos = -1;
while ((read_bytes = getline(&line, &len, f)) != -1) {
@@ -164,13 +152,35 @@ int main() {
perror("strdup");
goto cleanup;
}
-
- if (current_file && strcmp(new_tracks[track_count], current_file) == 0 && new_pos == -1) {
- new_pos = track_count;
- }
track_count++;
}
+ /* Re-query MPD state after editor to avoid stale data */
+ struct mpd_status *status = mpd_run_status(c);
+ if (status == NULL) {
+ fprintf(stderr, "Error getting status: %s\n", mpd_connection_get_error_message(c));
+ goto cleanup;
+ }
+ state = mpd_status_get_state(status);
+ current_pos = mpd_status_get_song_pos(status);
+ total_queue_len = mpd_status_get_queue_length(status);
+ mpd_status_free(status);
+
+ if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
+ struct mpd_song *song = mpd_run_current_song(c);
+ if (song != NULL) {
+ current_file = strdup(mpd_song_get_uri(song));
+ mpd_song_free(song);
+ }
+ }
+
+ /* Compute new_pos from fresh current_file */
+ for (int i = 0; i < track_count; i++) {
+ if (current_file && strcmp(new_tracks[i], current_file) == 0 && new_pos == -1) {
+ new_pos = i;
+ }
+ }
+
if (!mpd_command_list_begin(c, false)) {
fprintf(stderr, "Failed to start command list: %s\n", mpd_connection_get_error_message(c));
goto cleanup;
diff --git a/mpd/mpd_update_library.c b/mpd/mpd_update_library.c
@@ -1,153 +1,169 @@
+#include <ctype.h>
#include <mpd/client.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
#include <unistd.h>
-#include <ctype.h>
#define DEFAULT_HOST "localhost"
#define DEFAULT_PORT 6600
#define DEFAULT_BACKOFF 5
struct mpd_connection *conn() {
- const char *host = getenv("MPD_HOST");
- if (host == NULL || strlen(host) == 0) host = DEFAULT_HOST;
-
- unsigned port = DEFAULT_PORT;
- const char *port_str = getenv("MPD_PORT");
- if (port_str != NULL && strlen(port_str) > 0) port = (unsigned)atoi(port_str);
-
- struct mpd_connection *c = mpd_connection_new(host, port, 0);
- if (c == NULL) {
- fprintf(stderr, "Failed to create MPD connection object\n");
- return NULL;
- }
-
- if (mpd_connection_get_error(c) != MPD_ERROR_SUCCESS) {
- fprintf(stderr, "Error connecting to MPD (%s:%u): %s\n", host, port, mpd_connection_get_error_message(c));
- mpd_connection_free(c);
- return NULL;
- }
- return c;
+ const char *host = getenv("MPD_HOST");
+ if (host == NULL || strlen(host) == 0)
+ host = DEFAULT_HOST;
+
+ unsigned port = DEFAULT_PORT;
+ const char *port_str = getenv("MPD_PORT");
+ if (port_str != NULL && strlen(port_str) > 0)
+ port = (unsigned)atoi(port_str);
+
+ struct mpd_connection *c = mpd_connection_new(host, port, 0);
+ if (c == NULL) {
+ fprintf(stderr, "Failed to create MPD connection object\n");
+ return NULL;
+ }
+
+ if (mpd_connection_get_error(c) != MPD_ERROR_SUCCESS) {
+ fprintf(stderr, "Error connecting to MPD (%s:%u): %s\n", host, port,
+ mpd_connection_get_error_message(c));
+ mpd_connection_free(c);
+ return NULL;
+ }
+ return c;
}
-char* trim_whitespace(char* str) {
- char *end;
- while(isspace((unsigned char)*str)) str++;
- if(*str == 0) return str;
- end = str + strlen(str) - 1;
- while(end > str && isspace((unsigned char)*end)) end--;
- end[1] = '\0';
+char *trim_whitespace(char *str) {
+ char *end;
+ while (isspace((unsigned char)*str))
+ str++;
+ if (*str == 0)
return str;
+ end = str + strlen(str) - 1;
+ while (end > str && isspace((unsigned char)*end))
+ end--;
+ end[1] = '\0';
+ return str;
}
int main(int argc, char *argv[]) {
- if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
- printf("Usage: %s [input_file]\n", argv[0]);
- return 0;
- }
-
- FILE *input = stdin;
- if (argc > 1) {
- input = fopen(argv[1], "r");
- if (input == NULL) {
- perror("Error opening file");
- return 1;
- }
- } else if (isatty(STDIN_FILENO)) {
- fprintf(stderr, "Reading from stdin... (Press Ctrl+D to finish)\n");
- }
-
- char **top_dirs = NULL;
- int dir_count = 0;
- char *line = NULL;
- size_t len = 0;
- ssize_t read_bytes;
-
- while ((read_bytes = getline(&line, &len, input)) != -1) {
- char *trimmed = trim_whitespace(line);
- if (strlen(trimmed) == 0 || trimmed[0] == '#') continue;
-
- char *slash = strchr(trimmed, '/');
- if (slash != NULL) *slash = '\0';
-
- bool found = false;
- for (int i = 0; i < dir_count; i++) {
- if (strcmp(top_dirs[i], trimmed) == 0) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- char **temp_dirs = realloc(top_dirs, sizeof(char *) * (dir_count + 1));
- if (temp_dirs == NULL) {
- perror("realloc");
- break;
- }
- top_dirs = temp_dirs;
- top_dirs[dir_count] = strdup(trimmed);
- if (top_dirs[dir_count] == NULL) {
- perror("strdup");
- break;
- }
- dir_count++;
- }
- }
- free(line);
- if (input != stdin) fclose(input);
-
- if (dir_count == 0) {
- printf("No directories found in input.\n");
- for (int i = 0; i < dir_count; i++) free(top_dirs[i]);
- free(top_dirs);
- return 0;
- }
-
- printf("Found %d unique top-level directories to update.\n", dir_count);
-
- struct mpd_connection *c = conn();
- if (c == NULL) {
- for (int i = 0; i < dir_count; i++) free(top_dirs[i]);
- free(top_dirs);
- return 1;
+ if (argc > 1 &&
+ (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
+ printf("Usage: %s [input_file]\n", argv[0]);
+ return 0;
+ }
+
+ FILE *input = stdin;
+ if (argc > 1) {
+ input = fopen(argv[1], "r");
+ if (input == NULL) {
+ perror("Error opening file");
+ return 1;
}
-
- int backoff = DEFAULT_BACKOFF;
- const char *backoff_str = getenv("MPD_UPDATE_BACKOFF");
- if (backoff_str != NULL && strlen(backoff_str) > 0) backoff = atoi(backoff_str);
-
- int updated_count = 0;
- int error_count = 0;
-
+ } else if (isatty(STDIN_FILENO)) {
+ fprintf(stderr, "Reading from stdin... (Press Ctrl+D to finish)\n");
+ }
+
+ char **top_dirs = NULL;
+ int dir_count = 0;
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t read_bytes;
+
+ while ((read_bytes = getline(&line, &len, input)) != -1) {
+ char *trimmed = trim_whitespace(line);
+ if (strlen(trimmed) == 0 || trimmed[0] == '#')
+ continue;
+
+ char *slash = strchr(trimmed, '/');
+ if (slash != NULL)
+ *slash = '\0';
+
+ bool found = false;
for (int i = 0; i < dir_count; i++) {
- printf("Updating: '%s'\n", top_dirs[i]);
- unsigned job_id = mpd_run_update(c, top_dirs[i]);
- if (job_id == 0) {
- fprintf(stderr, " ✗ Failed: %s\n", mpd_connection_get_error_message(c));
- error_count++;
- mpd_connection_clear_error(c);
- } else {
- printf(" ✓ Success (Job ID: %u)\n", job_id);
- updated_count++;
- }
- if (i < dir_count - 1 && backoff > 0) sleep(backoff);
+ if (strcmp(top_dirs[i], trimmed) == 0) {
+ found = true;
+ break;
+ }
}
- printf("Update completed!\n");
- printf("Total directories processed: %d\n", dir_count);
- printf("Successfully updated: %d\n", updated_count);
- printf("Errors: %d\n", error_count);
-
- struct mpd_status *status = mpd_run_status(c);
- if (status != NULL) {
- if (mpd_status_get_update_id(status) > 0) printf("MPD is currently updating...\n");
- mpd_status_free(status);
+ if (!found) {
+ char **temp_dirs = realloc(top_dirs, sizeof(char *) * (dir_count + 1));
+ if (temp_dirs == NULL) {
+ perror("realloc");
+ break;
+ }
+ top_dirs = temp_dirs;
+ top_dirs[dir_count] = strdup(trimmed);
+ if (top_dirs[dir_count] == NULL) {
+ perror("strdup");
+ break;
+ }
+ dir_count++;
}
-
- for (int i = 0; i < dir_count; i++) free(top_dirs[i]);
+ }
+ free(line);
+ if (input != stdin)
+ fclose(input);
+
+ if (dir_count == 0) {
+ printf("No directories found in input.\n");
+ for (int i = 0; i < dir_count; i++)
+ free(top_dirs[i]);
free(top_dirs);
- mpd_connection_free(c);
return 0;
+ }
+
+ printf("Found %d unique top-level directories to update.\n", dir_count);
+
+ struct mpd_connection *c = conn();
+ if (c == NULL) {
+ for (int i = 0; i < dir_count; i++)
+ free(top_dirs[i]);
+ free(top_dirs);
+ return 1;
+ }
+
+ int backoff = DEFAULT_BACKOFF;
+ const char *backoff_str = getenv("MPD_UPDATE_BACKOFF");
+ if (backoff_str != NULL && strlen(backoff_str) > 0)
+ backoff = atoi(backoff_str);
+
+ int updated_count = 0;
+ int error_count = 0;
+
+ for (int i = 0; i < dir_count; i++) {
+ printf("Updating: '%s'\n", top_dirs[i]);
+ unsigned job_id = mpd_run_update(c, top_dirs[i]);
+ if (job_id == 0) {
+ fprintf(stderr, " ✗ Failed: %s\n", mpd_connection_get_error_message(c));
+ error_count++;
+ mpd_connection_clear_error(c);
+ } else {
+ printf(" ✓ Success (Job ID: %u)\n", job_id);
+ updated_count++;
+ }
+ if (i < dir_count - 1 && backoff > 0)
+ sleep(backoff);
+ }
+
+ printf("Update completed!\n");
+ printf("Total directories processed: %d\n", dir_count);
+ printf("Successfully updated: %d\n", updated_count);
+ printf("Errors: %d\n", error_count);
+
+ struct mpd_status *status = mpd_run_status(c);
+ if (status != NULL) {
+ if (mpd_status_get_update_id(status) > 0)
+ printf("MPD is currently updating...\n");
+ mpd_status_free(status);
+ }
+
+ for (int i = 0; i < dir_count; i++)
+ free(top_dirs[i]);
+ free(top_dirs);
+ mpd_connection_free(c);
+ return 0;
}
diff --git a/mpd/mpd_update_queue.c b/mpd/mpd_update_queue.c
@@ -48,35 +48,14 @@ int main(int argc, char *argv[]) {
return 1;
}
- struct mpd_status *status = mpd_run_status(c);
- if (status == NULL) {
- fprintf(stderr, "Error getting status: %s\n", mpd_connection_get_error_message(c));
- fclose(input);
- mpd_connection_free(c);
- return 1;
- }
-
- enum mpd_state state = mpd_status_get_state(status);
- int current_pos = mpd_status_get_song_pos(status);
- int total_queue_len = mpd_status_get_queue_length(status);
- mpd_status_free(status);
-
- char *current_file = NULL;
- if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
- struct mpd_song *song = mpd_run_current_song(c);
- if (song != NULL) {
- current_file = strdup(mpd_song_get_uri(song));
- mpd_song_free(song);
- }
- }
-
char **new_tracks = NULL;
int track_count = 0;
char *line = NULL;
size_t len = 0;
ssize_t read_bytes;
- int new_pos = -1;
+ char *current_file = NULL;
+ /* Read input file first, before querying MPD state */
while ((read_bytes = getline(&line, &len, input)) != -1) {
if (read_bytes > 0 && line[read_bytes - 1] == '\n') line[read_bytes - 1] = '\0';
if (read_bytes > 1 && line[read_bytes - 2] == '\r') line[read_bytes - 2] = '\0';
@@ -94,13 +73,36 @@ int main(int argc, char *argv[]) {
perror("strdup");
goto cleanup;
}
-
- if (current_file && strcmp(new_tracks[track_count], current_file) == 0 && new_pos == -1) {
- new_pos = track_count;
- }
track_count++;
}
+ /* Re-query MPD state before building command list */
+ struct mpd_status *status = mpd_run_status(c);
+ if (status == NULL) {
+ fprintf(stderr, "Error getting status: %s\n", mpd_connection_get_error_message(c));
+ goto cleanup;
+ }
+ enum mpd_state state = mpd_status_get_state(status);
+ int current_pos = mpd_status_get_song_pos(status);
+ int total_queue_len = mpd_status_get_queue_length(status);
+ mpd_status_free(status);
+
+ if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
+ struct mpd_song *song = mpd_run_current_song(c);
+ if (song != NULL) {
+ current_file = strdup(mpd_song_get_uri(song));
+ mpd_song_free(song);
+ }
+ }
+
+ /* Compute new_pos from fresh current_file */
+ int new_pos = -1;
+ for (int i = 0; i < track_count; i++) {
+ if (current_file && strcmp(new_tracks[i], current_file) == 0 && new_pos == -1) {
+ new_pos = i;
+ }
+ }
+
if (!mpd_command_list_begin(c, false)) {
fprintf(stderr, "Failed to start command list: %s\n", mpd_connection_get_error_message(c));
goto cleanup;