Commit Diff


commit - 184600a89b139d44c106a366c351bee471185137
commit + bf19b03e6400fa3a7573b0ba4fd057767f0adc22
blob - 61834acffd9976fb86f0c0e41dd7624eaa494618
blob + 8a11967a55fb6e34c043591ae23d80109c613d8c
--- player.c
+++ player.c
@@ -199,22 +199,38 @@ player_sendeof(void)
 int
 player_playnext(void)
 {
+	static char buf[512];
+	ssize_t r;
 	int fd = nextfd;
 
 	assert(nextfd != -1);
 	nextfd = -1;
 
-	/* XXX: use magic(5) for this, not file extensions */
-	if (strstr(nextpath, ".ogg") != NULL)
-		return play_oggvorbis(fd);
-	else if (strstr(nextpath, ".mp3") != NULL)
-		return play_mp3(fd);
-	else if (strstr(nextpath, ".flac") != NULL)
-		return play_flac(fd);
-	else if (strstr(nextpath, ".opus") != NULL)
+	r = read(fd, buf, sizeof(buf));
+
+	/* 8 byte is the larger magic number */
+	if (r < 8) {
+		log_warn("failed to read %s", nextpath);
+		goto err;
+	}
+
+	if (lseek(fd, 0, SEEK_SET) == -1) {
+		log_warn("lseek failed");
+		goto err;
+	}
+
+	if (memcmp(buf, "fLaC", 4) == 0)
+		return play_flac(fd);
+	if (memcmp(buf, "ID3", 3) == 0 ||
+	    memcmp(buf, "\xFF\xFB", 2) == 0)
+		return play_mp3(fd);
+	if (memmem(buf, r, "OpusHead", 8) != NULL)
 		return play_opus(fd);
+	if (memmem(buf, r, "OggS", 4) != NULL)
+		return play_oggvorbis(fd);
 
 	log_warnx("unknown file type for %s", nextpath);
+err:
 	close(fd);
 	return -1;
 }