diff --git a/docs/man/rpm-plugin-dbus-announce.8.md b/docs/man/rpm-plugin-dbus-announce.8.md index 6d0484ec53..6ee3eccd35 100644 --- a/docs/man/rpm-plugin-dbus-announce.8.md +++ b/docs/man/rpm-plugin-dbus-announce.8.md @@ -19,12 +19,21 @@ to the signals to be notified of the packages on the system change. DBus Signals ============ -Sends **StartTransaction** and **EndTransaction** messages from the -**/org/rpm/Transaction** object with the **org.rpm.Transaction** -interface. +Sends **StartTransaction**, **EndTransaction**, **StartTransactionDetails** +and **EndTransactionDetails** messages from the **/org/rpm/Transaction** +object with the **org.rpm.Transaction** interface. -The signal passes the DB cookie as a string and the transaction id as an -unsigned 32 bit integer. +The first two signals pass the DB cookie as a string and the transaction id +as an unsigned 32 bit integer. + +The second two signals, those "details", also pass the DB cookie as a string +and the transaction id as an unsigned 32 bit integer and then in addition +an array of strings containing space-separated string of values describing +the operation and the package NEVRA which are part of the transaction. +The last argument is a signed integer with the transaction result. + +The package operation can be one of "added", "removed", "rpmdb" or "restored" +(quotes for clarity only). Configuration ============= diff --git a/plugins/dbus_announce.c b/plugins/dbus_announce.c index 2c01e3f376..782055ceb8 100644 --- a/plugins/dbus_announce.c +++ b/plugins/dbus_announce.c @@ -83,14 +83,30 @@ static void dbus_announce_cleanup(rpmPlugin plugin) free(state); } +static void free_array(char ** array) +{ + int i; + + if (array == NULL) + return; + + for (i = 0; array[i]; i++) { + free(array[i]); + } + free(array); +} + static rpmRC send_ts_message(rpmPlugin plugin, const char * name, rpmts ts, int res) { struct dbus_announce_data * state = rpmPluginGetData(plugin); - DBusMessage* msg; + DBusMessage* msg = NULL; char * dbcookie = NULL; + char detail_name[128]; + char ** array = NULL; + int nElems, i; if (!state->bus) return RPMRC_OK; @@ -103,9 +119,77 @@ static rpmRC send_ts_message(rpmPlugin plugin, dbcookie = rpmdbCookie(rpmtsGetRdb(ts)); rpm_tid_t tid = rpmtsGetTid(ts); + + if (!dbus_message_append_args(msg, + DBUS_TYPE_STRING, &dbcookie, + DBUS_TYPE_UINT32, &tid, + DBUS_TYPE_INVALID)) + goto err; + + if (!dbus_connection_send(state->bus, msg, NULL)) + goto err; + + if (snprintf(detail_name, sizeof(detail_name), "%sDetails", name) >= sizeof(detail_name)) { + rpmlog(RPMLOG_WARNING, + "dbus_announce plugin: Static buffer for details signal name is not large enough, needs at least %u bytes\n", + (unsigned int)(strlen(name) + strlen("Details") + 1)); + goto err; + } + + dbus_message_unref(msg); + + /* it's used in the log below, thus to have proper signal name in there */ + name = detail_name; + msg = dbus_message_new_signal("/org/rpm/Transaction", /* object name */ + "org.rpm.Transaction", /* interface name */ + name); /* signal name */ + if (msg == NULL) + goto err; + + nElems = rpmtsNElements(ts); + array = (char **) malloc((nElems + 1 ) * sizeof(char *)); + if (array == NULL) + goto err; + + array[0] = NULL; + for (i = 0; i < nElems; i++) { + rpmte te = rpmtsElement(ts, i); + char *buff; + int buffln; + const char *op = "??"; + const char *nevra = rpmteNEVRA(te); + if (nevra == NULL) + nevra = ""; + switch (rpmteType (te)) { + case TR_ADDED: + op = "added"; + break; + case TR_REMOVED: + op = "removed"; + break; + case TR_RPMDB: + op = "rpmdb"; + break; + case TR_RESTORED: + op = "restored"; + break; + } + buffln = strlen(op) + 1 + strlen(nevra) + 1; + buff = (char *) malloc(sizeof(char) * buffln); + if (buff == NULL) + goto err; + /* encode as "operation SPACE nevra" */ + snprintf(buff, buffln, "%s %s", op, nevra); + array[i] = buff; + } + /* sentinel */ + array[nElems] = NULL; + if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &dbcookie, DBUS_TYPE_UINT32, &tid, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &array, nElems, + DBUS_TYPE_INT32, &res, DBUS_TYPE_INVALID)) goto err; @@ -115,6 +199,9 @@ static rpmRC send_ts_message(rpmPlugin plugin, dbus_connection_flush(state->bus); dbcookie = _free(dbcookie); + dbus_message_unref(msg); + free_array(array); + return RPMRC_OK; err: @@ -122,6 +209,9 @@ static rpmRC send_ts_message(rpmPlugin plugin, "dbus_announce plugin: Error sending message (%s)\n", name); dbcookie = _free(dbcookie); + if (msg != NULL) + dbus_message_unref(msg); + free_array(array); return RPMRC_OK; } diff --git a/plugins/org.rpm.Transaction.xml b/plugins/org.rpm.Transaction.xml new file mode 100644 index 0000000000..12ebe909f2 --- /dev/null +++ b/plugins/org.rpm.Transaction.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +