tools

various tools I have been using throughout the years
Log | Files | Refs | README | LICENSE

mpd_insert_next.c (2428B)


      1 #define _POSIX_C_SOURCE 200809L
      2 
      3 #include "mpd_common.h"
      4 
      5 #include <limits.h>
      6 #include <string.h>
      7 #include <unistd.h>
      8 
      9 static void usage(FILE *file, const char *program) {
     10   fprintf(file, "Usage: %s [--verbose] [FILE|-]\n", program);
     11 }
     12 
     13 int main(int argc, char **argv) {
     14   bool verbose = false;
     15   const char *path = NULL;
     16   for (int i = 1; i < argc; i++) {
     17     if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
     18       usage(stdout, argv[0]);
     19       return 0;
     20     }
     21     if (strcmp(argv[i], "--verbose") == 0) {
     22       verbose = true;
     23     } else if (argv[i][0] == '-' && strcmp(argv[i], "-") != 0) {
     24       usage(stderr, argv[0]);
     25       return 2;
     26     } else if (path == NULL) {
     27       path = argv[i];
     28     } else {
     29       usage(stderr, argv[0]);
     30       return 2;
     31     }
     32   }
     33 
     34   bool close_input;
     35   FILE *input = mt_open_input(path, &close_input);
     36   if (input == NULL)
     37     return 1;
     38   if (path == NULL && isatty(STDIN_FILENO))
     39     fprintf(stderr, "Reading tracks from stdin; press Ctrl-D to finish.\n");
     40 
     41   struct mt_strvec tracks;
     42   mt_strvec_init(&tracks);
     43   bool ok = mt_read_lines(input, &tracks);
     44   if (close_input && fclose(input) != 0) {
     45     perror("mpd: close input");
     46     ok = false;
     47   }
     48   if (!ok) {
     49     mt_strvec_clear(&tracks);
     50     return 1;
     51   }
     52 
     53   struct mpd_connection *connection = mt_connect();
     54   if (connection == NULL) {
     55     mt_strvec_clear(&tracks);
     56     return 1;
     57   }
     58   struct mt_player_state state;
     59   ok = mt_get_player_state(connection, &state);
     60   unsigned position = 0U;
     61   if (ok && state.song_pos != UINT_MAX) {
     62     if (state.song_pos == UINT_MAX - 1U) {
     63       fprintf(stderr, "mpd: current queue position is too large\n");
     64       ok = false;
     65     } else {
     66       position = state.song_pos + 1U;
     67     }
     68   }
     69   if (ok) {
     70     enum mt_state_match match =
     71         mt_player_state_is(connection, state.queue_version, state.song_id);
     72     if (match == MT_STATE_CHANGED) {
     73       fprintf(stderr,
     74               "mpd: player or queue changed before insertion; retry the "
     75               "command\n");
     76       ok = false;
     77     } else if (match == MT_STATE_ERROR) {
     78       ok = false;
     79     }
     80   }
     81   if (ok)
     82     ok = mt_insert_queue(connection, &tracks, position, verbose);
     83   if (ok)
     84     printf("Inserted %zu track%s at queue position %u.\n", tracks.len,
     85            tracks.len == 1U ? "" : "s", position);
     86 
     87   mt_player_state_clear(&state);
     88   mpd_connection_free(connection);
     89   mt_strvec_clear(&tracks);
     90   return ok ? 0 : 1;
     91 }