vpd

video player daemon
git clone git://git.kocotian.pl/vpd.git
Log | Files | Refs | README | LICENSE

commit d4b6b1ad5828f78af7baa8a13bdddc6de5be40d0
parent 59d100f4b74fa2e6e59eecdfe17cc2203a055b2b
Author: kocotian <kocotian@kocotian.pl>
Date:   Mon, 29 Mar 2021 18:48:09 +0200

Communication with vpd via actions (vpc)

Diffstat:
MMakefile | 5++++-
Avpc.c | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mvpd.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
3 files changed, 189 insertions(+), 7 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ CFLAGS = -std=c99 -pedantic -Wall -Wextra -Wconversion -O2 -all: vpd +all: vpd vpc util.o: util.c ${CC} ${CFLAGS} -c -o $@ $< @@ -8,4 +8,7 @@ util.o: util.c vpd: vpd.c util.o ${CC} ${CFLAGS} -o $@ $^ +vpc: vpc.c util.o + ${CC} ${CFLAGS} -o $@ $^ + .PHONY: all diff --git a/vpc.c b/vpc.c @@ -0,0 +1,121 @@ +#include <arpa/inet.h> +#include <linux/limits.h> +#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> + +#include "arg.h" +#include "util.h" + +typedef enum { + ActionNop, + ActionGetQueue, + ActionExitDaemon +} Action; + +static int action_getQueue(int fd); +static int action_exitDaemon(int fd); +static int handle(int fd, char *action); +static void usage(void); + +char *argv0; + +static int +action_getQueue(int fd) +{ + int i; + char filename[PATH_MAX]; + union { + char input[2]; + uint16_t output; + } converter; + i = 0; + while (read(fd, converter.input, 2) == 2 && converter.output) { + read(fd, filename, PATH_MAX); + printf("* item #%d: %.*s\n", i, converter.output, filename); + ++i; + } + printf("queue has %d videos\n", i); + return 0; +} + +static int +action_exitDaemon(int fd) +{ + char exitCode; + if (read(fd, &exitCode, 1) != 1) + die("read:"); /* FIXME: theoretically it can write "read: Success" */ + printf("daemon returned %d\n", exitCode); + return 0; +} + +static int +handle(int fd, char *arg) +{ + Action action; + if (!strcmp(arg, "queue")) + action = ActionGetQueue; + else if (!strcmp(arg, "exit")) + action = ActionExitDaemon; + + write(fd, &action, 1); + switch (action) { + case ActionGetQueue: action_getQueue(fd); break; + case ActionExitDaemon: action_exitDaemon(fd); break; + default: break; + } + return 0; +} + +static void +usage(void) +{ + die("usage: %s ACTION", argv0); +} + +int +main(int argc, char *argv[]) +{ + char *action; + char *host = "127.0.0.1"; + uint16_t port = 7111; + int sockfd; + struct sockaddr_in sockaddr_in; + + ARGBEGIN { + case 'h': + if ((host = ARGF()) == NULL) + usage(); + break; + case 'p': + if ((action = ARGF()) == NULL) + usage(); + /* FIXME: some comparsion to make sure that value will not overflow */ + port = (uint16_t)strtol(action, NULL, 10); + break; + default: + usage(); break; + } ARGEND + + action = argv[0]; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + die("socket:"); + + sockaddr_in.sin_family = AF_INET; + sockaddr_in.sin_addr.s_addr = inet_addr(host); + sockaddr_in.sin_port = htons(port); + + if (connect(sockfd, (struct sockaddr *)&sockaddr_in, + sizeof sockaddr_in) < 0) + die("connect:"); + + handle(sockfd, action); + + close(sockfd); + return 0; +} diff --git a/vpd.c b/vpd.c @@ -12,10 +12,21 @@ #define MAX_QUEUELEN 256 +typedef enum { + ActionNop, + ActionGetQueue, + ActionExitDaemon +} Action; + typedef struct { char filename[PATH_MAX]; + size_t fnlen; } QueueItem; +static int action_getQueue(int fd); +static int action_exitDaemon(int fd); +static void setup(void); +static int takeAction(int fd); static void usage(void); char *argv0; @@ -24,6 +35,54 @@ static QueueItem queue[MAX_QUEUELEN]; static QueueItem *queueBeginning; static size_t queueLength; +static int +action_getQueue(int fd) +{ + size_t i; + union { + uint16_t input; + char output[2]; + } converter; + for (i = 0; i < queueLength; ++i) { + converter.input = (uint16_t)(*(queueBeginning + i)).fnlen; + write(fd, converter.output, 2); + write(fd, (*(queueBeginning + i)).filename, (*(queueBeginning + i)).fnlen); + } + i = 0; + write(fd, &i, 2); + return 0; +} + +static int +action_exitDaemon(int fd) +{ + char i = 0; + write(fd, &i, 1); + exit(0); + return 0; +} + +static int +takeAction(int fd) +{ + Action action; + if (read(fd, &action, 1) != 1) + return 1; + switch (action) { + case ActionGetQueue: action_getQueue(fd); break; + case ActionExitDaemon: action_exitDaemon(fd); break; + default: break; + } + return 0; +} + +static void +setup(void) +{ + queueBeginning = queue; + queueLength = 0; +} + static void usage(void) { @@ -36,8 +95,6 @@ main(int argc, char *argv[]) int serverfd, clientfd; struct sockaddr_in serveraddr_in, clientaddr_in; socklen_t clientaddr_len; - ssize_t rb; - char buffer[BUFSIZ]; ARGBEGIN { default: @@ -47,6 +104,8 @@ main(int argc, char *argv[]) if (argc != 2) usage(); + setup(); + if ((serverfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) die("socket:"); @@ -61,10 +120,9 @@ main(int argc, char *argv[]) die("listen:"); while (1) { - if ((clientfd = accept(serverfd, (struct sockaddr *)&clientaddr_in, - &clientaddr_len)) < 0) { - perror("accept"); - } + clientfd = accept(serverfd, (struct sockaddr *)&clientaddr_in, + &clientaddr_len); + takeAction(clientfd); close(clientfd); } close(serverfd);