+static void cf_playlists(char attribute((unused)) **argv) {
+ char **vec;
+
+ if(disorder_playlists(getclient(), &vec, 0))
+ exit(EXIT_FAILURE);
+ while(*vec)
+ xprintf("%s\n", nullcheck(utf82mb(*vec++)));
+}
+
+static void cf_playlist_del(char **argv) {
+ if(disorder_playlist_delete(getclient(), argv[0]))
+ exit(EXIT_FAILURE);
+}
+
+static void cf_playlist_get(char **argv) {
+ char **vec;
+
+ if(disorder_playlist_get(getclient(), argv[0], &vec, 0))
+ exit(EXIT_FAILURE);
+ while(*vec)
+ xprintf("%s\n", nullcheck(utf82mb(*vec++)));
+}
+
+static void cf_playlist_set(char **argv) {
+ struct vector v[1];
+ FILE *input;
+ const char *tag;
+ char *l;
+
+ if(argv[1]) {
+ // Read track list from file
+ if(!(input = fopen(argv[1], "r")))
+ disorder_fatal(errno, "opening %s", argv[1]);
+ tag = argv[1];
+ } else {
+ // Read track list from standard input
+ input = stdin;
+ tag = "stdin";
+ }
+ vector_init(v);
+ while(!inputline(tag, input, &l, '\n')) {
+ if(!strcmp(l, "."))
+ break;
+ vector_append(v, l);
+ }
+ if(ferror(input))
+ disorder_fatal(errno, "reading %s", tag);
+ if(input != stdin)
+ fclose(input);
+ if(disorder_playlist_lock(getclient(), argv[0])
+ || disorder_playlist_set(getclient(), argv[0], v->vec, v->nvec)
+ || disorder_playlist_unlock(getclient()))
+ exit(EXIT_FAILURE);
+}
+