tmisu

Notification to stdout daemon
git clone https://git.inz.fi/tmisu/
Log | Files | Refs | README | LICENSE

commit 101db10bffabd31fc6ebeca554a24017a2d219e1
parent b5700bfebd96c5b763a0166d6e9bc183e1afb88a
Author: Sweets <Sweets@users.noreply.github.com>
Date:   Sun,  5 Jul 2020 15:10:47 -0700

Some refactoring, +actions +hints

Diffstat:
MMakefile | 6+++---
Mcallbacks.c | 160++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mcallbacks.h | 12++++++++++++
Dformat.c | 97-------------------------------------------------------------------------------
Dformat.h | 7-------
Mtiramisu.h | 4++++
6 files changed, 129 insertions(+), 157 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,17 +1,17 @@ TARGET = tiramisu -SRC := tiramisu.c callbacks.c format.c +SRC := tiramisu.c callbacks.c PREFIX ?= /usr/local -CFLAGS = -Wall +CFLAGS = -Wall -Wno-unused-value IFLAGS = $(shell pkg-config --cflags glib-2.0 gio-2.0) LFLAGS = $(shell pkg-config --libs glib-2.0 gio-2.0) all: $(TARGET) $(TARGET): $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(IFLAGS) $(SRC) $(LFLAGS) -o $(TARGET) + $(CC) $(CFLAGS) $(IFLAGS) $(SRC) $(LFLAGS) -o $(TARGET) install: $(TARGET) mkdir -p $(DESTDIR)$(PREFIX)/bin diff --git a/callbacks.c b/callbacks.c @@ -1,79 +1,145 @@ +#include <stdio.h> + #include "tiramisu.h" #include "callbacks.h" -#include "format.h" unsigned int notification_id = 0; +char *sanitize(char *string, char *out) { + memset(out, 0, strlen(out)); + + while (*string) { + if (*string == '"') + strcat(out, "\\\""); + else if (*string == '\n') + strcat(out, "\\n"); + else + out[strlen(out)] = *string; + string++; + } + + return out; +} + void method_handler(GDBusConnection *connection, const gchar *sender, const gchar *object, const gchar *interface, const gchar *method, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { + GVariantIter iterator; + gchar *app_name; + guint32 replaces_id; + gchar *app_icon; + gchar *summary; + gchar *body; + gchar **actions; + GVariant *hints; + gint32 timeout; GVariant *return_value = NULL; - if (!strcmp(method, "Notify")) { - GVariantIter iterator; - - g_variant_iter_init(&iterator, parameters); - - gchar *app_name; - g_variant_iter_next(&iterator, "s", &app_name); + if (!strcmp(method, "Notify")) + goto output; - guint32 replaces_id; - g_variant_iter_next(&iterator, "u", &replaces_id); - - gchar *app_icon; - g_variant_iter_next(&iterator, "s", &app_icon); + if (!strcmp(method, "GetServerInformation")) { + return_value = g_variant_new("(ssss)", + "tiramisu", "Sweets", "1.0", "1.2"); + goto flush; + } - gchar *summary; - g_variant_iter_next(&iterator, "s", &summary); + print("Unhandled: %s %s\n", method, sender); - gchar *body; - g_variant_iter_next(&iterator, "s", &body); +output: + notification_id++; + + g_variant_iter_init(&iterator, parameters); + g_variant_iter_next(&iterator, "s", &app_name); + g_variant_iter_next(&iterator, "u", &replaces_id); + g_variant_iter_next(&iterator, "s", &app_icon); + g_variant_iter_next(&iterator, "s", &summary); + g_variant_iter_next(&iterator, "s", &body); + g_variant_iter_next(&iterator, "^a&s", &actions); + g_variant_iter_next(&iterator, "@a{sv}", &hints); + g_variant_iter_next(&iterator, "i", &timeout); + + char *sanitized = (char *)calloc(512, sizeof(char)); + + printf("%s: %s\n%s: %s", + "app_name", sanitize(app_name, sanitized), + "app_icon", sanitize(app_icon, sanitized)); + printf("%s: %u\n%s: %d\n", + "replaces_id", replaces_id, + "timeout", timeout); + printf("%s\n", "hints"); + + gchar *key; + GVariant *value; + + const char *int_format = "\t%s: %d\n"; + const char *uint_format = "\t%s: %u\n"; + + unsigned int index = 0; + + g_variant_iter_init(&iterator, hints); + while (g_variant_iter_loop(&iterator, "{sv}", &key, NULL)) { + + /* There has to be a better way. glib, why? */ + + if ((value = g_variant_lookup_value(hints, key, GT_STRING))) + printf("\t%s: %s\n", key, + sanitize(g_variant_dup_string(value, NULL), sanitized)); + else if ((value = g_variant_lookup_value(hints, key, GT_INT16))) + printf(int_format, key, g_variant_get_int16(value)); + else if ((value = g_variant_lookup_value(hints, key, GT_INT32))) + printf(int_format, key, g_variant_get_int32(value)); + else if ((value = g_variant_lookup_value(hints, key, GT_INT64))) + printf(int_format, key, g_variant_get_int64(value)); + else if ((value = g_variant_lookup_value(hints, key, GT_UINT16))) + printf(uint_format, key, g_variant_get_uint16(value)); + else if ((value = g_variant_lookup_value(hints, key, GT_UINT32))) + printf(uint_format, key, g_variant_get_uint32(value)); + else if ((value = g_variant_lookup_value(hints, key, GT_UINT64))) + printf(uint_format, key, g_variant_get_uint64(value)); + else if ((value = g_variant_lookup_value(hints, key, GT_DOUBLE))) + printf("\t%s: %f\n", key, g_variant_get_double(value)); + else if ((value = g_variant_lookup_value(hints, key, GT_BYTE))) + printf("\t%s: %x\n", key, g_variant_get_byte(value)); + else if ((value = g_variant_lookup_value(hints, key, GT_BOOL))) { + if (g_variant_get_boolean(value)) + printf("\t%s: 1\n", key); + else + printf("\t%s: 0\n", key); + } - GVariant **actions; - g_variant_iter_next(&iterator, "as", &actions); + } - GVariant *hints; - g_variant_iter_next(&iterator, "@a{s*}", &hints); + printf("%s\n", "actions"); - gint32 timeout; - g_variant_iter_next(&iterator, "i", &timeout); + while (actions[index + 1]) { + printf("\t%s = '%s'\n", actions[index], actions[++index]); + index++; + } - output_notification(app_name, replaces_id, app_icon, summary, body, - actions, hints, timeout); + printf("%s: %s\n%s: %s", + "summary", sanitize(summary, sanitized), + "body", sanitize(body, sanitized)); - return_value = g_variant_new("(u)", notification_id++); - goto flush; - } + return_value = g_variant_new("(u)", notification_id); - if (!strcmp(method, "GetServerInformation")) { - return_value = g_variant_new("(ssss)", - "tiramisu", "Sweets", "1.0", "1.2"); - goto flush; - } + fflush(stdout); + free(sanitized); - goto unhandled; + goto flush; flush: g_dbus_method_invocation_return_value(invocation, return_value); g_dbus_connection_flush(connection, NULL, NULL, NULL); return; -unhandled: -#ifdef DEBUG - print("Unhandled: %s %s\n", method, sender); -#else - return; -#endif - } void bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) { -#ifdef DEBUG print("%s\n", "Bus has been acquired."); -#endif guint registered_object; registered_object = g_dbus_connection_register_object(connection, @@ -85,9 +151,7 @@ void bus_acquired(GDBusConnection *connection, const gchar *name, NULL); if (!registered_object) { -#ifdef DEBUG print("%s\n", "Unable to register."); -#endif stop_main_loop(NULL); } } @@ -95,9 +159,7 @@ void bus_acquired(GDBusConnection *connection, const gchar *name, void name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) { dbus_connection = connection; -#ifdef DEBUG print("%s\n", "Name has been acquired."); -#endif } void name_lost(GDBusConnection *connection, const gchar *name, @@ -105,14 +167,12 @@ void name_lost(GDBusConnection *connection, const gchar *name, // we lost the Notifications daemon name or couldn't acquire it, shutdown if (!connection) { - print("%s; %s\n", + printf("%s; %s\n", "Unable to connect to acquire org.freedesktop.Notifications", "could not connect to dbus."); stop_main_loop(NULL); } -#ifdef DEBUG else print("%s\n", "Successfully acquired org.freedesktop.Notifications"); -#endif } diff --git a/callbacks.h b/callbacks.h @@ -3,8 +3,20 @@ #include <gio/gio.h> #include <glib.h> +#define GT_STRING G_VARIANT_TYPE_STRING +#define GT_INT16 G_VARIANT_TYPE_INT16 +#define GT_INT32 G_VARIANT_TYPE_INT32 +#define GT_INT64 G_VARIANT_TYPE_INT64 +#define GT_UINT16 G_VARIANT_TYPE_UINT16 +#define GT_UINT32 G_VARIANT_TYPE_UINT32 +#define GT_UINT64 G_VARIANT_TYPE_UINT64 +#define GT_DOUBLE G_VARIANT_TYPE_DOUBLE +#define GT_BOOL G_VARIANT_TYPE_BOOLEAN +#define GT_BYTE G_VARIANT_TYPE_BYTE + extern unsigned int notification_id; +char *sanitize(char*, char*); void method_handler(GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar*, GVariant*, GDBusMethodInvocation*, gpointer); diff --git a/format.c b/format.c @@ -1,97 +0,0 @@ -#include <stdio.h> - -#include "config.h" -#include "format.h" -#include "tiramisu.h" - -char* escape_quotes(char *str, char *out) { - memset(out, 0, strlen(out)); - while (*str) { - if (*str == '"') - strcat(out, "\\\""); - else - out[strlen(out)] = *str; - str++; - } - - return out; -} - -void output_notification(gchar *app_name, guint32 replaces_id, gchar *app_icon, - gchar *summary, gchar *body, GVariant **actions, GVariant *hints, - gint32 timeout) { - - char *escaped_string = (char *)calloc(512, sizeof(char)); - - gsize index = 0; - while (actions[index] && actions[index + 1]) { - g_print(", \"%s\": \"%s\"", g_variant_dup_string(actions[index], NULL), - g_variant_dup_string(actions[index++], NULL)); - index++; - } - - -#ifdef PRINT_JSON - - printf("{ \"app_name\": \"%s\",", escape_quotes(app_name, escaped_string)); - printf(" \"app_icon\": \"%s\",", escape_quotes(app_icon, escaped_string)); - printf(" \"replaces_id\": %u, \"timeout\": %d,", replaces_id, timeout); - printf(" \"hints\": { "); - - const char *int_format = ", \"%s\": %d"; - const char *uint_format = ", \"%s\": %u"; - - GVariantIter iterator; - gchar *key; - GVariant *v; // Short-hand for `value` - - g_variant_iter_init(&iterator, hints); - while (g_variant_iter_loop(&iterator, "{s*}", &key, NULL)) { - - /* Horrible code, but for now it's just in testing. */ - - if ((v = g_variant_lookup_value(hints, key, G_VARIANT_TYPE_STRING))) - printf(", \"%s\": \"%s\"", key, - escape_quotes(g_variant_dup_string(v, NULL), escaped_string)); - else if ((v = g_variant_lookup_value(hints, key, G_VARIANT_TYPE_INT16))) - printf(int_format, key, g_variant_get_int16(v)); - else if ((v = g_variant_lookup_value(hints, key, G_VARIANT_TYPE_INT32))) - printf(int_format, key, g_variant_get_int32(v)); - else if ((v = g_variant_lookup_value(hints, key, G_VARIANT_TYPE_INT64))) - printf(int_format, key, g_variant_get_int64(v)); - else if ((v = g_variant_lookup_value(hints, key,G_VARIANT_TYPE_UINT16))) - printf(uint_format, key, g_variant_get_uint16(v)); - else if ((v = g_variant_lookup_value(hints, key,G_VARIANT_TYPE_UINT32))) - printf(uint_format, key, g_variant_get_uint32(v)); - else if ((v = g_variant_lookup_value(hints, key,G_VARIANT_TYPE_UINT64))) - printf(uint_format, key, g_variant_get_uint64(v)); - else if ((v = g_variant_lookup_value(hints, key,G_VARIANT_TYPE_DOUBLE))) - printf(", \"%s\": %f", key, g_variant_get_double(v)); - else if ((v=g_variant_lookup_value(hints,key,G_VARIANT_TYPE_BOOLEAN))) { - if (g_variant_get_boolean(v)) - printf(", \"%s\": 1", key); - else - printf(", \"%s\": 0", key); - } else if ((v = g_variant_lookup_value(hints, key,G_VARIANT_TYPE_BYTE))) - printf(", \"%s\": %x", key, g_variant_get_byte(v)); - - } - - printf(" },"); - printf(" \"summary\": \"%s\",", escape_quotes(summary, escaped_string)); - printf(" \"body\": \"%s\" }\n", escape_quotes(body, escaped_string)); - -#else - - printf("%s%s%s%s%u%s%d%s%s%s%s\n", - app_name, OUTPUT_DELIMITER, - app_icon, OUTPUT_DELIMITER, - replaces_id, OUTPUT_DELIMITER, - timeout, OUTPUT_DELIMITER, - summary, OUTPUT_DELIMITER, body); - -#endif - - fflush(stdout); - free(escaped_string); -} diff --git a/format.h b/format.h @@ -1,7 +0,0 @@ -#pragma once - -#include <gio/gio.h> -#include <glib.h> - -void output_notification(gchar*, guint32, gchar*, gchar*, gchar*, GVariant**, - GVariant*, gint32); diff --git a/tiramisu.h b/tiramisu.h @@ -12,6 +12,10 @@ extern GDBusConnection *dbus_connection; extern GDBusNodeInfo *introspection; extern GMainLoop *main_loop; +#ifdef DEBUG #define print(...) fprintf(stderr, __VA_ARGS__); +#else +#define print(...) (void)(__VA_ARGS__); +#endif gboolean stop_main_loop(gpointer);