commit - 5f42a6c6cec1b37dd9f653a36d005b5dc1c58be0
commit + fad0fb69c1b7616f933c497887967078ff4dd111
blob - e25201404c849f9f177eca8e796465a6095e4b8c
blob + b4a0234f60989c1b4841fc215ae5c2dd62dc01f0
--- ctl.c
+++ ctl.c
}
static int
-enqueue_tracks(char **files)
-{
- char res[PATH_MAX];
- int enq = 0;
-
- for (; *files != NULL; ++files) {
- memset(&res, 0, sizeof(res));
- if (realpath(*files, res) == NULL) {
- log_warn("realpath %s", *files);
- continue;
- }
-
- imsg_compose(ibuf, IMSG_CTL_ADD, 0, 0, -1,
- res, sizeof(res));
- enq++;
- }
-
- return enq == 0;
-}
-
-static int
-jump_req(const char *arg)
-{
- char path[PATH_MAX];
-
- memset(path, 0, sizeof(path));
- strlcpy(path, arg, sizeof(path));
- imsg_compose(ibuf, IMSG_CTL_JUMP, 0, 0, -1, path, sizeof(path));
- return 0;
-}
-
-static void
-print_error_message(const char *prfx, struct imsg *imsg)
-{
- size_t datalen;
- char *msg;
-
- datalen = IMSG_DATA_SIZE(*imsg);
- if ((msg = calloc(1, datalen)) == NULL)
- fatal("calloc %zu", datalen);
- memcpy(msg, imsg->data, datalen);
- if (datalen == 0 || msg[datalen-1] != '\0')
- fatalx("malformed error message");
-
- log_warnx("%s: %s", prfx, msg);
- free(msg);
-}
-
-static int
-show_add(struct imsg *imsg, int *ret, char ***files)
-{
- if (**files == NULL) {
- log_warnx("received more replies than file sent");
- *ret = 1;
- return 1;
- }
-
- if (imsg->hdr.type == IMSG_CTL_ERR)
- print_error_message(**files, imsg);
- else if (imsg->hdr.type == IMSG_CTL_ADD)
- log_debug("enqueued %s", **files);
- else
- fatalx("got invalid message %d", imsg->hdr.type);
-
- (*files)++;
- return (**files) == NULL;
-}
-
-static int
-show_complete(struct parse_result *res, struct imsg *imsg, int *ret)
-{
- struct player_status s;
- size_t datalen;
-
- if (imsg->hdr.type == IMSG_CTL_ERR) {
- print_error_message("show failed", imsg);
- *ret = 1;
- return 1;
- }
-
- datalen = IMSG_DATA_SIZE(*imsg);
- if (datalen == 0)
- return 1;
-
- if (datalen != sizeof(s))
- fatalx("%s: data size mismatch", __func__);
- memcpy(&s, imsg->data, sizeof(s));
- if (s.path[sizeof(s.path)-1] != '\0')
- fatalx("%s: data corrupted?", __func__);
-
- if (res->pretty)
- printf("%c ", s.status == STATE_PLAYING ? '>' : ' ');
- printf("%s\n", s.path);
- return 0;
-}
-
-static int
-show_status(struct imsg *imsg, int *ret)
-{
- struct player_status s;
- size_t datalen;
-
- if (imsg->hdr.type == IMSG_CTL_ERR) {
- print_error_message("show failed", imsg);
- *ret = 1;
- return 1;
- }
-
- if (imsg->hdr.type != IMSG_CTL_STATUS)
- fatalx("%s: got wrong reply", __func__);
-
- datalen = IMSG_DATA_SIZE(*imsg);
- if (datalen != sizeof(s))
- fatalx("%s: data size mismatch", __func__);
- memcpy(&s, imsg->data, sizeof(s));
- if (s.path[sizeof(s.path)-1] != '\0')
- fatalx("%s: data corrupted?", __func__);
-
- switch (s.status) {
- case STATE_STOPPED:
- printf("stopped ");
- break;
- case STATE_PLAYING:
- printf("playing ");
- break;
- case STATE_PAUSED:
- printf("paused ");
- break;
- default:
- printf("unknown ");
- break;
- }
-
- printf("%s\n", s.path);
- printf("repeat one %s\nrepeat all %s\n",
- s.rp.repeat_one ? "on" : "off",
- s.rp.repeat_all ? "on" : "off");
- return 1;
-}
-
-static int
-show_load(struct parse_result *res, struct imsg *imsg, int *ret)
+load_files(struct parse_result *res, int *ret)
{
FILE *f;
const char *file;
size_t linesize = 0, i = 0, n;
ssize_t linelen, curr = -1;
- if (imsg->hdr.type == IMSG_CTL_ERR) {
- print_error_message("load failed", imsg);
- *ret = 1;
- return 1;
- }
-
- if (imsg->hdr.type == IMSG_CTL_ADD)
- return 0;
-
- if (imsg->hdr.type == IMSG_CTL_COMMIT)
- return 1;
-
- if (imsg->hdr.type != IMSG_CTL_BEGIN)
- fatalx("got unexpected message %d", imsg->hdr.type);
-
if (res->file == NULL)
f = stdin;
else if ((f = fopen(res->file, "r")) == NULL) {
return 0;
}
-static int
-show_monitor(struct parse_result *res, struct imsg *imsg, int *ret)
+static const char *
+imsg_strerror(struct imsg *imsg)
{
- int type;
+ size_t datalen;
+ const char *msg;
- if (imsg->hdr.type != IMSG_CTL_MONITOR) {
- log_warnx("wrong message type received: %d",
- imsg->hdr.type);
- *ret = 1;
- return 1;
- }
+ datalen = IMSG_DATA_SIZE(*imsg);
+ msg = imsg->data;
+ if (datalen == 0 || msg[datalen-1] != '\0')
+ fatalx("malformed error message");
- if (IMSG_DATA_SIZE(*imsg) != sizeof(type)) {
- log_warnx("size mismatch");
- *ret = 1;
- return 1;
- }
-
- memcpy(&type, imsg->data, sizeof(type));
- if (type < 0 || type > IMSG__LAST) {
- log_warnx("wrong monitor type received");
- *ret = 1;
- return 1;
- }
-
- if (!res->monitor[type])
- return 0;
+ return msg;
+}
+static const char *
+imsg_name(int type)
+{
switch (type) {
case IMSG_CTL_PLAY:
- puts("play");
- break;
+ return "play";
case IMSG_CTL_TOGGLE_PLAY:
- puts("toggle");
- break;
+ return "toggle";
case IMSG_CTL_PAUSE:
- puts("pause");
- break;
+ return "pause";
case IMSG_CTL_STOP:
- puts("stop");
- break;
+ return "stop";
case IMSG_CTL_RESTART:
- puts("restart");
- break;
+ return "restart";
case IMSG_CTL_FLUSH:
- puts("flush");
- break;
+ return "flush";
case IMSG_CTL_NEXT:
- puts("next");
- break;
+ return "next";
case IMSG_CTL_PREV:
- puts("prev");
- break;
+ return "prev";
case IMSG_CTL_JUMP:
- puts("jump");
- break;
+ return "jump";
case IMSG_CTL_REPEAT:
- puts("repeat");
- break;
+ return "repeat";
case IMSG_CTL_ADD:
- puts("add");
- break;
+ return "add";
case IMSG_CTL_COMMIT:
- puts("load");
- break;
+ return "load";
default:
- puts("unknown");
- break;
+ return "unknown";
}
-
- fflush(stdout);
- return 0;
}
static int
ctlaction(struct parse_result *res)
{
+ char path[PATH_MAX];
struct imsg imsg;
+ struct player_status ps;
+ size_t datalen;
ssize_t n;
- int ret = 0, done = 1;
+ int i, type, ret = 0, done = 1;
char **files;
switch (res->action) {
break;
case ADD:
done = 0;
- files = res->files;
- ret = enqueue_tracks(res->files);
+ i = 0;
+ for (files = res->files; *files != NULL; ++files) {
+ memset(&path, 0, sizeof(path));
+ if (realpath(*files, path) == NULL) {
+ log_warn("realpath %s", *files);
+ continue;
+ }
+
+ imsg_compose(ibuf, IMSG_CTL_ADD, 0, 0, -1,
+ path, sizeof(path));
+ i++;
+ }
+ ret = i == 0;
break;
case FLUSH:
imsg_compose(ibuf, IMSG_CTL_FLUSH, 0, 0, -1, NULL, 0);
break;
case JUMP:
done = 0;
- ret = jump_req(res->file);
+ memset(path, 0, sizeof(path));
+ strlcpy(path, res->file, sizeof(path));
+ imsg_compose(ibuf, IMSG_CTL_JUMP, 0, 0, -1,
+ path, sizeof(path));
break;
case REPEAT:
imsg_compose(ibuf, IMSG_CTL_REPEAT, 0, 0, -1,
imsg_flush(ibuf);
+ i = 0;
while (!done) {
if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
fatalx("imsg_read error");
if (n == 0)
break;
+ if (imsg.hdr.type == IMSG_CTL_ERR) {
+ log_warnx("%s: %s", res->ctl->name,
+ imsg_strerror(&imsg));
+ ret = 1;
+ done = 1;
+ break;
+ }
+
+ datalen = IMSG_DATA_SIZE(imsg);
+
switch (res->action) {
case ADD:
- done = show_add(&imsg, &ret, &files);
+ if (files[i] == NULL)
+ fatalx("received more replies than "
+ "files enqueued.");
+
+ if (imsg.hdr.type == IMSG_CTL_ADD)
+ log_debug("enqueued %s", files[i]);
+ else
+ fatalx("invalid message %d",
+ imsg.hdr.type);
+ i++;
+ done = files[i] == NULL;
break;
case SHOW:
- done = show_complete(res, &imsg, &ret);
+ if (datalen == 0) {
+ done = 1;
+ break;
+ }
+ if (datalen != sizeof(ps))
+ fatalx("data size mismatch");
+ memcpy(&ps, imsg.data, sizeof(ps));
+ if (ps.path[sizeof(ps.path) - 1] != '\0')
+ fatalx("received corrupted data");
+ if (res->pretty) {
+ char c = ' ';
+ if (ps.status == STATE_PLAYING)
+ c = '>';
+ printf("%c ", c);
+ }
+ puts(ps.path);
break;
case PLAY:
case TOGGLE:
case NEXT:
case PREV:
case JUMP:
- done = show_status(&imsg, &ret);
+ if (imsg.hdr.type != IMSG_CTL_STATUS)
+ fatalx("invalid message %d",
+ imsg.hdr.type);
+
+ if (datalen != sizeof(ps))
+ fatalx("data size mismatch");
+ memcpy(&ps, imsg.data, sizeof(ps));
+ if (ps.path[sizeof(ps.path) - 1] != '\0')
+ fatalx("received corrupted data");
+
+ if (ps.status == STATE_STOPPED)
+ printf("stopped ");
+ else if (ps.status == STATE_PLAYING)
+ printf("playing ");
+ else if (ps.status == STATE_PAUSED)
+ printf("paused ");
+ else
+ printf("unknown ");
+
+ puts(ps.path);
+ printf("repat one %s\nrepeat all %s\n",
+ ps.rp.repeat_one ? "on" : "off",
+ ps.rp.repeat_all ? "on" : "off");
+
+ done = 1;
break;
case LOAD:
- done = show_load(res, &imsg, &ret);
+ if (imsg.hdr.type == IMSG_CTL_ADD)
+ break;
+ if (imsg.hdr.type == IMSG_CTL_COMMIT) {
+ done = 1;
+ break;
+ }
+
+ if (imsg.hdr.type != IMSG_CTL_BEGIN)
+ fatalx("invalid message %d",
+ imsg.hdr.type);
+
+ load_files(res, &ret);
break;
case MONITOR:
- done = show_monitor(res, &imsg, &ret);
+ if (imsg.hdr.type != IMSG_CTL_MONITOR)
+ fatalx("invalid message %d",
+ imsg.hdr.type);
+
+ if (datalen != sizeof(type))
+ fatalx("data size mismatch");
+
+ memcpy(&type, imsg.data, sizeof(type));
+ if (type < 0 || type > IMSG__LAST)
+ fatalx("received corrupted data");
+
+ if (!res->monitor[type])
+ break;
+
+ puts(imsg_name(type));
+ fflush(stdout);
break;
default:
done = 1;