Bug Summary

File:shell/ev-daemon.c
Warning:line 212, column 52
Access to field 'loaded_id' results in a dereference of a null pointer (loaded from variable 'doc')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ev-daemon.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/shell -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D LECTORDATADIR="/usr/share/lector" -D CAFEDATADIR="/usr/share" -I .. -I .. -I ../cut-n-paste/zoom-control/ -I ../cut-n-paste/toolbar-editor/ -I ../cut-n-paste/smclient/ -I ../libdocument -I ../libdocument -I ../libview -I ../libview -I ../libmisc -I ../properties -D CAFEICONDIR="/usr/share/pixmaps" -D BINDIR="/usr/bin" -D LIBEXECDIR="/usr/libexec" -D LECTOR_COMPILATION -I /usr/include/libxml2 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/libsecret-1 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gio-unix-2.0 -D CDK_MULTIHEAD_SAFE -D CTK_MULTIHEAD_SAFE -D LECTORDATADIR="/usr/share/lector" -D CAFEDATADIR="/usr/share" -I .. -I .. -D LIBEXECDIR="/usr/libexec" -D LECTOR_COMPILATION -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/shell -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-02-17-124057-54187-1 -x c ev-daemon.c
1/* ev-daemon.c
2 * this file is part of lector, a cafe document viewer
3 *
4 * Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
5 * Copyright © 2010, 2012 Christian Persch
6 *
7 * Lector is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * Lector is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#include "config.h"
23
24#define G_LOG_DOMAIN"LectorDaemon" "LectorDaemon"
25#include <glib.h>
26#include <glib/gstdio.h>
27#include <gio/gio.h>
28#include <string.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/wait.h>
32#include <fcntl.h>
33#include <unistd.h>
34
35#include "ev-daemon-gdbus-generated.h"
36
37#define EV_DBUS_DAEMON_NAME"org.cafe.lector.Daemon" "org.cafe.lector.Daemon"
38#define EV_DBUS_DAEMON_INTERFACE_NAME"org.cafe.lector.Daemon" "org.cafe.lector.Daemon"
39#define EV_DBUS_DAEMON_OBJECT_PATH"/org/cafe/lector/Daemon" "/org/cafe/lector/Daemon"
40
41#define EV_DBUS_WINDOW_INTERFACE_NAME"org.cafe.lector.Window" "org.cafe.lector.Window"
42
43#define DAEMON_TIMEOUT(30) (30) /* seconds */
44
45#define LOGg_debug g_debug
46
47
48#define EV_TYPE_DAEMON_APPLICATION(ev_daemon_application_get_type ()) (ev_daemon_application_get_type ())
49#define EV_DAEMON_APPLICATION(object)((((EvDaemonApplication*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((object)), ((ev_daemon_application_get_type
()))))))
(G_TYPE_CHECK_INSTANCE_CAST ((object), EV_TYPE_DAEMON_APPLICATION, EvDaemonApplication)(((EvDaemonApplication*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((object)), ((ev_daemon_application_get_type
())))))
)
50#define EV_DAEMON_APPLICATION_CLASS(klass)((((EvDaemonApplicationClass*) (void *) g_type_check_class_cast
((GTypeClass*) ((klass)), ((ev_daemon_application_get_type (
)))))))
(G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_DAEMON_APPLICATION, EvDaemonApplicationClass)(((EvDaemonApplicationClass*) (void *) g_type_check_class_cast
((GTypeClass*) ((klass)), ((ev_daemon_application_get_type (
))))))
)
51#define EV_IS_DAEMON_APPLICATION(object)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(object)); GType __t = ((ev_daemon_application_get_type ()));
gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
))))
(G_TYPE_CHECK_INSTANCE_TYPE ((object), EV_TYPE_DAEMON_APPLICATION)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(object)); GType __t = ((ev_daemon_application_get_type ()));
gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))
)
52#define EV_IS_DAEMON_APPLICATION_CLASS(klass)(((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((ev_daemon_application_get_type ())); gboolean
__r; if (!__class) __r = (0); else if (__class->g_type ==
__t) __r = (!(0)); else __r = g_type_check_class_is_a (__class
, __t); __r; }))))
(G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_DAEMON_APPLICATION)((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((ev_daemon_application_get_type ())); gboolean
__r; if (!__class) __r = (0); else if (__class->g_type ==
__t) __r = (!(0)); else __r = g_type_check_class_is_a (__class
, __t); __r; })))
)
53#define EV_DAEMON_APPLICATION_GET_CLASS(obj)((((EvDaemonApplicationClass*) (((GTypeInstance*) ((obj)))->
g_class))))
(G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_DAEMON_APPLICATION, EvDaemonApplicationClass)(((EvDaemonApplicationClass*) (((GTypeInstance*) ((obj)))->
g_class)))
)
54
55typedef struct _EvDaemonApplication EvDaemonApplication;
56typedef struct _EvDaemonApplicationClass EvDaemonApplicationClass;
57
58struct _EvDaemonApplicationClass {
59 GApplicationClass parent_class;
60};
61
62struct _EvDaemonApplication
63{
64 GApplication parent_instance;
65
66 EvDaemon *daemon;
67 GHashTable *pending_invocations;
68 GList *docs;
69};
70
71static GType ev_daemon_application_get_type (void);
72G_DEFINE_TYPE (EvDaemonApplication, ev_daemon_application, G_TYPE_APPLICATION)static void ev_daemon_application_init (EvDaemonApplication *
self); static void ev_daemon_application_class_init (EvDaemonApplicationClass
*klass); static GType ev_daemon_application_get_type_once (void
); static gpointer ev_daemon_application_parent_class = ((void
*)0); static gint EvDaemonApplication_private_offset; static void
ev_daemon_application_class_intern_init (gpointer klass) { ev_daemon_application_parent_class
= g_type_class_peek_parent (klass); if (EvDaemonApplication_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &EvDaemonApplication_private_offset
); ev_daemon_application_class_init ((EvDaemonApplicationClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
ev_daemon_application_get_instance_private (EvDaemonApplication
*self) { return (((gpointer) ((guint8*) (self) + (glong) (EvDaemonApplication_private_offset
)))); } GType ev_daemon_application_get_type (void) { static gsize
static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); (void) (0 ? (gpointer) *(
&static_g_define_type_id) : ((void*)0)); (!(__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = ev_daemon_application_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType ev_daemon_application_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((g_application_get_type ()), g_intern_static_string ("EvDaemonApplication"
), sizeof (EvDaemonApplicationClass), (GClassInitFunc)(void (
*)(void)) ev_daemon_application_class_intern_init, sizeof (EvDaemonApplication
), (GInstanceInitFunc)(void (*)(void)) ev_daemon_application_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
73
74typedef struct {
75 gchar *dbus_name;
76 gchar *uri;
77 guint watch_id;
78 guint loaded_id;
79} EvDoc;
80
81static void
82ev_doc_free (EvDoc *doc)
83{
84 if (!doc)
85 return;
86
87 g_free (doc->dbus_name);
88 g_free (doc->uri);
89
90 g_bus_unwatch_name (doc->watch_id);
91
92 g_free (doc);
93}
94
95static EvDoc *
96ev_daemon_application_find_doc (EvDaemonApplication *application,
97 const gchar *uri)
98{
99 GList *l;
100
101 for (l = application->docs; l != NULL((void*)0); l = l->next) {
102 EvDoc *doc = (EvDoc *)l->data;
103
104 if (strcmp (doc->uri, uri) == 0)
105 return doc;
106 }
107
108 return NULL((void*)0);
109}
110
111static gboolean
112spawn_lector (const gchar *uri)
113{
114 gchar *argv[3];
115 gboolean retval;
116 GError *error = NULL((void*)0);
117
118 /* TODO Check that the uri exists */
119 argv[0] = g_build_filename (BINDIR"/usr/bin", "lector", NULL((void*)0));
120 argv[1] = (gchar *) uri;
121 argv[2] = NULL((void*)0);
122
123 retval = g_spawn_async (NULL((void*)0) /* wd */, argv, NULL((void*)0) /* env */,
124 0, NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
125 if (!retval) {
126 g_printerr ("Error spawning lector for uri %s: %s\n", uri, error->message);
127 g_error_free (error);
128 }
129 g_free (argv[0]);
130
131 return retval;
132}
133
134static void
135name_appeared_cb (GDBusConnection *connection,
136 const gchar *name,
137 const gchar *name_owner,
138 gpointer user_data)
139{
140 LOGg_debug ("Watch name'%s' appeared with owner '%s'", name, name_owner);
141}
142
143static void
144name_vanished_cb (GDBusConnection *connection,
145 const gchar *name,
146 gpointer user_data)
147{
148 EvDaemonApplication *application = EV_DAEMON_APPLICATION (user_data)((((EvDaemonApplication*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((user_data)), ((ev_daemon_application_get_type
()))))))
;
149 GList *l;
150
151 LOGg_debug ("Watch name'%s' disappeared", name);
152
153 for (l = application->docs; l != NULL((void*)0); l = l->next) {
154 EvDoc *doc = (EvDoc *) l->data;
155
156 if (strcmp (doc->dbus_name, name) != 0)
157 continue;
158
159 LOGg_debug ("Watch found URI '%s' for name; removing", doc->uri);
160
161 application->docs = g_list_delete_link (application->docs, l);
162 ev_doc_free (doc);
163
164 g_application_release (G_APPLICATION (application)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((application)), ((g_application_get_type ()))))))
);
165
166 return;
167 }
168}
169
170static void
171process_pending_invocations (EvDaemonApplication *application,
172 const gchar *uri,
173 const gchar *dbus_name)
174{
175 GList *l;
176 GList *uri_invocations;
177
178 LOGg_debug ("RegisterDocument process pending invocations for URI %s", uri);
179 uri_invocations = g_hash_table_lookup (application->pending_invocations, uri);
180
181 for (l = uri_invocations; l != NULL((void*)0); l = l->next) {
182 GDBusMethodInvocation *invocation;
183
184 invocation = (GDBusMethodInvocation *)l->data;
185 g_dbus_method_invocation_return_value (invocation,
186 g_variant_new ("(s)", dbus_name));
187 }
188
189 g_list_free (uri_invocations);
190 g_hash_table_remove (application->pending_invocations, uri);
191}
192
193static void
194document_loaded_cb (GDBusConnection *connection,
195 const gchar *sender_name,
196 const gchar *object_path,
197 const gchar *interface_name,
198 const gchar *signal_name,
199 GVariant *parameters,
200 gpointer user_data)
201{
202 EvDaemonApplication *application = EV_DAEMON_APPLICATION (user_data)((((EvDaemonApplication*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((user_data)), ((ev_daemon_application_get_type
()))))))
;
203 const gchar *uri;
204 EvDoc *doc;
205
206 g_variant_get (parameters, "(&s)", &uri);
207 doc = ev_daemon_application_find_doc (application, uri);
1
Value assigned to 'doc'
208 if (doc != NULL((void*)0) && strcmp (uri, doc->uri) == 0) {
2
Assuming 'doc' is equal to NULL
209 process_pending_invocations (application, uri, sender_name);
210 }
211
212 g_dbus_connection_signal_unsubscribe (connection, doc->loaded_id);
3
Access to field 'loaded_id' results in a dereference of a null pointer (loaded from variable 'doc')
213 doc->loaded_id = 0;
214}
215
216static gboolean
217handle_register_document_cb (EvDaemon *object,
218 GDBusMethodInvocation *invocation,
219 const gchar *uri,
220 EvDaemonApplication *application)
221{
222 GDBusConnection *connection;
223 const char *sender;
224 EvDoc *doc;
225
226 doc = ev_daemon_application_find_doc (application, uri);
227 if (doc != NULL((void*)0)) {
228 LOGg_debug ("RegisterDocument found owner '%s' for URI '%s'", doc->dbus_name, uri);
229 ev_daemon_complete_register_document (object, invocation, doc->dbus_name);
230
231 return TRUE(!(0));
232 }
233
234 sender = g_dbus_method_invocation_get_sender (invocation);
235 connection = g_dbus_method_invocation_get_connection (invocation);
236
237 LOGg_debug ("RegisterDocument registered owner '%s' for URI '%s'", sender, uri);
238
239 doc = g_new (EvDoc, 1)((EvDoc *) g_malloc_n ((1), sizeof (EvDoc)));
240 doc->dbus_name = g_strdup (sender)g_strdup_inline (sender);
241 doc->uri = g_strdup (uri)g_strdup_inline (uri);
242
243 application->docs = g_list_prepend (application->docs, doc);
244
245 doc->loaded_id = g_dbus_connection_signal_subscribe (connection,
246 doc->dbus_name,
247 EV_DBUS_WINDOW_INTERFACE_NAME"org.cafe.lector.Window",
248 "DocumentLoaded",
249 NULL((void*)0),
250 NULL((void*)0),
251 0,
252 document_loaded_cb,
253 application, NULL((void*)0));
254 doc->watch_id = g_bus_watch_name_on_connection (connection,
255 sender,
256 G_BUS_NAME_WATCHER_FLAGS_NONE,
257 name_appeared_cb,
258 name_vanished_cb,
259 application, NULL((void*)0));
260
261 ev_daemon_complete_register_document (object, invocation, "");
262
263 g_application_hold (G_APPLICATION (application)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((application)), ((g_application_get_type ()))))))
);
264
265 return TRUE(!(0));
266}
267
268static gboolean
269handle_unregister_document_cb (EvDaemon *object,
270 GDBusMethodInvocation *invocation,
271 const gchar *uri,
272 EvDaemonApplication *application)
273{
274 EvDoc *doc;
275 const char *sender;
276
277 LOGg_debug ("UnregisterDocument URI '%s'", uri);
278
279 doc = ev_daemon_application_find_doc (application, uri);
280 if (doc == NULL((void*)0)) {
281 LOGg_debug ("UnregisterDocument URI was not registered!");
282 g_dbus_method_invocation_return_error_literal (invocation,
283 G_DBUS_ERRORg_dbus_error_quark(),
284 G_DBUS_ERROR_INVALID_ARGS,
285 "URI not registered");
286 return TRUE(!(0));
287 }
288
289 sender = g_dbus_method_invocation_get_sender (invocation);
290 if (strcmp (doc->dbus_name, sender) != 0) {
291 LOGg_debug ("UnregisterDocument called by non-owner (owner '%s' sender '%s')",
292 doc->dbus_name, sender);
293
294 g_dbus_method_invocation_return_error_literal (invocation,
295 G_DBUS_ERRORg_dbus_error_quark(),
296 G_DBUS_ERROR_BAD_ADDRESS,
297 "Only owner can call this method");
298 return TRUE(!(0));
299 }
300
301 application->docs = g_list_remove (application->docs, doc);
302
303 if (doc->loaded_id != 0) {
304 g_dbus_connection_signal_unsubscribe (g_dbus_method_invocation_get_connection (invocation),
305 doc->loaded_id);
306 doc->loaded_id = 0;
307 }
308
309 ev_doc_free (doc);
310
311 ev_daemon_complete_unregister_document (object, invocation);
312
313 g_application_release (G_APPLICATION (application)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((application)), ((g_application_get_type ()))))))
);
314
315 return TRUE(!(0));
316}
317
318static gboolean
319handle_find_document_cb (EvDaemon *object,
320 GDBusMethodInvocation *invocation,
321 const gchar *uri,
322 gboolean spawn,
323 EvDaemonApplication *application)
324{
325 EvDoc *doc;
326
327 LOGg_debug ("FindDocument URI '%s'", uri);
328
329 doc = ev_daemon_application_find_doc (application, uri);
330 if (doc != NULL((void*)0)) {
331 ev_daemon_complete_find_document (object, invocation, doc->dbus_name);
332
333 return TRUE(!(0));
334 }
335
336 if (spawn) {
337 GList *uri_invocations;
338 gboolean ret_val = TRUE(!(0));
339
340 uri_invocations = g_hash_table_lookup (application->pending_invocations, uri);
341
342 if (uri_invocations == NULL((void*)0)) {
343 /* Only spawn once. */
344 ret_val = spawn_lector (uri);
345 }
346
347 if (ret_val) {
348 /* Only defer DBUS answer if lector was succesfully spawned */
349 uri_invocations = g_list_prepend (uri_invocations, invocation);
350 g_hash_table_insert (application->pending_invocations,
351 g_strdup (uri)g_strdup_inline (uri),
352 uri_invocations);
353 return TRUE(!(0));
354 }
355 }
356
357 LOGg_debug ("FindDocument URI '%s' was not registered!", uri);
358 // FIXME: shouldn't this return an error then?
359 ev_daemon_complete_find_document (object, invocation, "");
360
361 return TRUE(!(0));
362}
363
364/* ------------------------------------------------------------------------- */
365
366static gboolean
367ev_daemon_application_dbus_register (GApplication *gapplication,
368 GDBusConnection *connection,
369 const gchar *object_path,
370 GError **error)
371{
372 EvDaemonApplication *application = EV_DAEMON_APPLICATION (gapplication)((((EvDaemonApplication*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((gapplication)), ((ev_daemon_application_get_type
()))))))
;
373 EvDaemon *skeleton;
374
375 if (!G_APPLICATION_CLASS (ev_daemon_application_parent_class)((((GApplicationClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ev_daemon_application_parent_class)), ((g_application_get_type
()))))))
->dbus_register (gapplication,
376 connection,
377 object_path,
378 error))
379 return FALSE(0);
380
381 skeleton = ev_daemon_skeleton_new ();
382 if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton)((((GDBusInterfaceSkeleton*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((skeleton)), ((g_dbus_interface_skeleton_get_type
()))))))
,
383 connection,
384 EV_DBUS_DAEMON_OBJECT_PATH"/org/cafe/lector/Daemon",
385 error)) {
386 g_object_unref (skeleton);
387 return FALSE(0);
388 }
389
390 application->daemon = skeleton;
391
392 g_signal_connect (skeleton, "handle-register-document",g_signal_connect_data ((skeleton), ("handle-register-document"
), (((GCallback) (handle_register_document_cb))), (application
), ((void*)0), (GConnectFlags) 0)
393 G_CALLBACK (handle_register_document_cb), application)g_signal_connect_data ((skeleton), ("handle-register-document"
), (((GCallback) (handle_register_document_cb))), (application
), ((void*)0), (GConnectFlags) 0)
;
394 g_signal_connect (skeleton, "handle-unregister-document",g_signal_connect_data ((skeleton), ("handle-unregister-document"
), (((GCallback) (handle_unregister_document_cb))), (application
), ((void*)0), (GConnectFlags) 0)
395 G_CALLBACK (handle_unregister_document_cb), application)g_signal_connect_data ((skeleton), ("handle-unregister-document"
), (((GCallback) (handle_unregister_document_cb))), (application
), ((void*)0), (GConnectFlags) 0)
;
396 g_signal_connect (skeleton, "handle-find-document",g_signal_connect_data ((skeleton), ("handle-find-document"), (
((GCallback) (handle_find_document_cb))), (application), ((void
*)0), (GConnectFlags) 0)
397 G_CALLBACK (handle_find_document_cb), application)g_signal_connect_data ((skeleton), ("handle-find-document"), (
((GCallback) (handle_find_document_cb))), (application), ((void
*)0), (GConnectFlags) 0)
;
398 return TRUE(!(0));
399}
400
401static void
402ev_daemon_application_dbus_unregister (GApplication *gapplication,
403 GDBusConnection *connection,
404 const gchar *object_path)
405{
406 EvDaemonApplication *application = EV_DAEMON_APPLICATION (gapplication)((((EvDaemonApplication*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((gapplication)), ((ev_daemon_application_get_type
()))))))
;
407
408 if (application->daemon) {
409 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (application->daemon)((((GDBusInterfaceSkeleton*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((application->daemon)), ((g_dbus_interface_skeleton_get_type
()))))))
);
410 g_object_unref (application->daemon);
411 application->daemon = NULL((void*)0);
412 }
413
414 G_APPLICATION_CLASS (ev_daemon_application_parent_class)((((GApplicationClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ev_daemon_application_parent_class)), ((g_application_get_type
()))))))
->dbus_unregister (gapplication,
415 connection,
416 object_path);
417}
418
419static void
420ev_daemon_application_init (EvDaemonApplication *application)
421{
422 application->pending_invocations = g_hash_table_new_full (g_str_hash,
423 g_str_equal,
424 (GDestroyNotify) g_free,
425 NULL((void*)0));
426}
427
428static void
429ev_daemon_application_finalize (GObject *object)
430{
431 EvDaemonApplication *application = EV_DAEMON_APPLICATION (object)((((EvDaemonApplication*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((object)), ((ev_daemon_application_get_type
()))))))
;
432
433 g_warn_if_fail (g_hash_table_size (application->pending_invocations) == 0)do { if (g_hash_table_size (application->pending_invocations
) == 0) ; else g_warn_message ("LectorDaemon", "ev-daemon.c",
433, ((const char*) (__func__)), "g_hash_table_size (application->pending_invocations) == 0"
); } while (0)
;
434 g_hash_table_destroy (application->pending_invocations);
435
436 g_list_free_full (application->docs, (GDestroyNotify) ev_doc_free);
437
438 G_OBJECT_CLASS (ev_daemon_application_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((ev_daemon_application_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
439}
440
441static void
442ev_daemon_application_class_init (EvDaemonApplicationClass *klass)
443{
444 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
445 GApplicationClass *g_application_class = G_APPLICATION_CLASS (klass)((((GApplicationClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((g_application_get_type ()))))))
;
446
447 object_class->finalize = ev_daemon_application_finalize;
448
449 g_application_class->dbus_register = ev_daemon_application_dbus_register;
450 g_application_class->dbus_unregister = ev_daemon_application_dbus_unregister;
451}
452
453/* ------------------------------------------------------------------------- */
454
455gint
456main (gint argc, gchar **argv)
457{
458 GApplication *application;
459 const GApplicationFlags flags = G_APPLICATION_IS_SERVICE;
460 GError *error = NULL((void*)0);
461 int status;
462
463 g_set_prgname ("lector-daemon");
464
465 application = g_object_new (EV_TYPE_DAEMON_APPLICATION(ev_daemon_application_get_type ()),
466 "application-id", EV_DBUS_DAEMON_NAME"org.cafe.lector.Daemon",
467 "flags", flags,
468 NULL((void*)0));
469 g_application_set_inactivity_timeout (application, DAEMON_TIMEOUT(30));
470
471 if (!g_application_register (application, NULL((void*)0), &error)) {
472 g_printerr ("Failed to register: %s\n", error->message);
473 g_error_free (error);
474 g_object_unref (application);
475
476 return 1;
477 }
478
479 status = g_application_run (application, 0, NULL((void*)0));
480 g_object_unref (application);
481
482 return status;
483}