prezzyd/prezzyc.c
2024-12-28 10:36:36 +13:00

146 lines
3.5 KiB
C

/*
* prezzyc
* Copyright (c) 2024 Jeremy Baxter.
*/
#define _PREZZYC_C_
#define _DEFAULT_SOURCE
#ifndef BUILD_DATE
#define BUILD_DATE "1970-01-01"
#endif
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "prezzyipc.h"
#include "discord_rpc.h"
static PrezzyIpcPacket **packets;
static int packetCount;
void
addPacket(PrezzyProperty property, PrezzyPayloadType type,
char *pString, int64_t pInteger)
{
PrezzyIpcPacket *p;
size_t len;
p = malloc(sizeof(PrezzyIpcPacket));
p->property = property;
p->type = type;
if (type == PLT_STRING) {
len = strlen(pString) + 1;
p->pString = malloc(len * sizeof(char));
strbcpy(p->pString, pString, len);
} else
p->pInteger = pInteger;
packetCount++;
packets = realloc(packets,
packetCount * sizeof(PrezzyIpcPacket *));
packets[packetCount - 1] = p;
}
int
getServer(const char *socketPath)
{
struct sockaddr_un addr;
int fd;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strbcpy(addr.sun_path, socketPath, sizeof(addr.sun_path) - 1);
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
err(1, "failed to create IPC client socket");
if (connect(fd, (struct sockaddr *)&addr,
sizeof(struct sockaddr_un)) == -1)
err(1, "failed to establish connection to IPC daemon");
return fd;
}
void
usage(void)
{
fputs(
"usage: prezzyc [-aV] [-d details] [-I icon] [-i tooltip]\n"
" [-L large-image] [-l tooltip] [-s state]\n"
" [-P limit] [-p size] [-T end] [-t start]\n",
stderr);
}
int
main(int argc, char **argv)
{
char *buffer;
ssize_t sz;
int ch, i;
int server;
if (argc < 2) { /* no options? */
usage();
return 1;
}
while ((ch = getopt(argc, argv, "ad:I:i:L:l:P:p:s:T:t:V")) != -1) {
switch (ch) {
case 'a': addPacket(PREZZY_TIMESTAMP_START, PLT_INT64, NULL, time(NULL)); break;
case 'd': addPacket(PREZZY_DETAILS, PLT_STRING, optarg, 0); break;
case 'I': addPacket(PREZZY_ICON, PLT_STRING, optarg, 0); break;
case 'i': addPacket(PREZZY_ICON_TOOLTIP, PLT_STRING, optarg, 0); break;
case 'L': addPacket(PREZZY_LARGE_IMAGE, PLT_STRING, optarg, 0); break;
case 'l': addPacket(PREZZY_LARGE_TOOLTIP, PLT_STRING, optarg, 0); break;
case 's': addPacket(PREZZY_STATE, PLT_STRING, optarg, 0); break;
case 'P': addPacket(PREZZY_PARTY_LIMIT, PLT_INT, NULL,
squashLong(strtol(optarg, NULL, 10))); break;
case 'p': addPacket(PREZZY_PARTY_SIZE, PLT_INT, NULL,
squashLong(strtol(optarg, NULL, 10))); break;
case 'T': addPacket(PREZZY_TIMESTAMP_END, PLT_INT64, NULL,
strtol(optarg, NULL, 10)); break;
case 't': addPacket(PREZZY_TIMESTAMP_START, PLT_INT64, NULL,
strtol(optarg, NULL, 10)); break;
case 'V':
printf("prezzyc version 0.1 built on " BUILD_DATE "\n");
return 0;
break;
}
}
if (argc - optind > 0) { /* extra arguments? */
usage();
return 1;
}
server = getServer(PREZZY_SOCK);
for (i = 0; i < packetCount; i++) {
buffer = fromIpcPacket(*packets[i]);
write(server, buffer, strlen(buffer));
free(buffer);
}
write(server, "\0", 1);
buffer = malloc(PREZZY_PACKET_MAX * sizeof(char));
memset(buffer, 0, PREZZY_PACKET_MAX);
while ((sz = read(server, buffer, PREZZY_PACKET_MAX - 1)) > 0) {
if (buffer[0] != 0)
errx(1, "IPC error %d: %s", buffer[0], buffer + 1);
}
if (sz == -1)
err(1, "failed to read from IPC server");
for (i = 0; i < packetCount; i++) {
if (packets[i]->type == PLT_STRING)
free(packets[i]->pString);
free(packets[i]);
}
free(packets);
return 0;
}