1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
/*
Copyright (C) 2009 RedHat inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "dbus.h"
#include "dbus_common.h"
DBusConnection* s_dbus_conn;
/*
* DBus member calls
*/
/* helpers */
static DBusMessage* new_call_msg(const char* method)
{
DBusMessage* msg = dbus_message_new_method_call(ABRTD_DBUS_NAME, ABRTD_DBUS_PATH, ABRTD_DBUS_IFACE, method);
if (!msg)
die_out_of_memory();
return msg;
}
static DBusMessage* send_get_reply_and_unref(DBusMessage* msg)
{
dbus_uint32_t serial;
if (TRUE != dbus_connection_send(s_dbus_conn, msg, &serial))
error_msg_and_die("Error sending DBus message");
dbus_message_unref(msg);
while (true)
{
DBusMessage *received = dbus_connection_pop_message(s_dbus_conn);
if (!received)
{
if (FALSE == dbus_connection_read_write(s_dbus_conn, -1))
error_msg_and_die("dbus connection closed");
continue;
}
int tp = dbus_message_get_type(received);
const char *error_str = dbus_message_get_error_name(received);
#if 0
/* Debugging */
printf("type:%u (CALL:%u, RETURN:%u, ERROR:%u, SIGNAL:%u)\n", tp,
DBUS_MESSAGE_TYPE_METHOD_CALL,
DBUS_MESSAGE_TYPE_METHOD_RETURN,
DBUS_MESSAGE_TYPE_ERROR,
DBUS_MESSAGE_TYPE_SIGNAL
);
const char *sender = dbus_message_get_sender(received);
if (sender)
printf("sender: %s\n", sender);
const char *path = dbus_message_get_path(received);
if (path)
printf("path: %s\n", path);
const char *member = dbus_message_get_member(received);
if (member)
printf("member: %s\n", member);
const char *interface = dbus_message_get_interface(received);
if (interface)
printf("interface: %s\n", interface);
const char *destination = dbus_message_get_destination(received);
if (destination)
printf("destination: %s\n", destination);
if (error_str)
printf("error: '%s'\n", error_str);
#endif
DBusError err;
dbus_error_init(&err);
if (dbus_message_is_signal(received, ABRTD_DBUS_IFACE, "Update"))
{
const char *update_msg;
if (!dbus_message_get_args(received, &err,
DBUS_TYPE_STRING, &update_msg,
DBUS_TYPE_INVALID))
{
error_msg_and_die("dbus Update message: arguments mismatch");
}
printf(">> %s\n", update_msg);
}
else if (dbus_message_is_signal(received, ABRTD_DBUS_IFACE, "Warning"))
{
const char *warning_msg;
if (!dbus_message_get_args(received, &err,
DBUS_TYPE_STRING, &warning_msg,
DBUS_TYPE_INVALID))
{
error_msg_and_die("dbus Warning message: arguments mismatch");
}
log(">! %s\n", warning_msg);
}
else
if (tp == DBUS_MESSAGE_TYPE_METHOD_RETURN
&& dbus_message_get_reply_serial(received) == serial
) {
return received;
}
else
if (tp == DBUS_MESSAGE_TYPE_ERROR
&& dbus_message_get_reply_serial(received) == serial
) {
error_msg_and_die("dbus call returned error: '%s'", error_str);
}
dbus_message_unref(received);
}
}
void handle_dbus_err(bool error_flag, DBusError *err)
{
if (dbus_error_is_set(err))
{
error_msg("dbus error: %s", err->message);
/* dbus_error_free(&err); */
error_flag = true;
}
if (!error_flag)
return;
error_msg_and_die(
"error requesting DBus name %s, possible reasons: "
"abrt run by non-root; dbus config is incorrect; "
"or dbus daemon needs to be restarted to reload dbus config",
ABRTD_DBUS_NAME);
}
int32_t call_DeleteDebugDump(const char* crash_id)
{
DBusMessage* msg = new_call_msg(__func__ + 5);
dbus_message_append_args(msg,
DBUS_TYPE_STRING, &crash_id,
DBUS_TYPE_INVALID);
DBusMessage *reply = send_get_reply_and_unref(msg);
DBusMessageIter in_iter;
dbus_message_iter_init(reply, &in_iter);
int32_t result;
int r = load_val(&in_iter, result);
if (r != ABRT_DBUS_LAST_FIELD) /* more values present, or bad type */
error_msg_and_die("dbus call %s: return type mismatch", __func__ + 5);
dbus_message_unref(reply);
return result;
}
|