Bug Summary

File:libslab/bookmark-agent.c
Warning:line 691, column 48
Out of bound memory access (access exceeds upper limit of memory block)

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 bookmark-agent.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 -fhalf-no-semantic-interposition -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/libslab -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="libslab" -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/cafe-desktop-2.0 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -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/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/librsvg-2.0 -I /usr/include/cafe-menus -D PIC -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/libslab -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-08-06-111517-113088-1 -x c bookmark-agent.c
1/*
2 * This file is part of the Main Menu.
3 *
4 * Copyright (c) 2007 Novell, Inc.
5 *
6 * The Main Menu is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * The Main Menu is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * the Main Menu; if not, write to the Free Software Foundation, Inc., 51
18 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "bookmark-agent.h"
22
23#ifdef HAVE_CONFIG_H1
24# include <config.h>
25#else
26# define PACKAGE"cafe-control-center" "cafe-main-menu"
27#endif
28
29#include <ctk/ctk.h>
30
31#include <string.h>
32#include <stdlib.h>
33#include <glib/gi18n-lib.h>
34#include <glib/gstdio.h>
35#include <gio/gio.h>
36
37#include "libslab-utils.h"
38
39#define USER_APPS_STORE_FILE_NAME"applications.xbel" "applications.xbel"
40#define USER_DOCS_STORE_FILE_NAME"documents.xbel" "documents.xbel"
41#define USER_DIRS_STORE_FILE_NAME"places.xbel" "places.xbel"
42#define SYSTEM_STORE_FILE_NAME"system-items.xbel" "system-items.xbel"
43#define CALC_TEMPLATE_FILE_NAME"empty.ots" "empty.ots"
44#define WRITER_TEMPLATE_FILE_NAME"empty.ott" "empty.ott"
45
46#define CTK_BOOKMARKS_FILE"bookmarks" "bookmarks"
47
48#define TYPE_IS_RECENT(type)((type) == BOOKMARK_STORE_RECENT_APPS || (type) == BOOKMARK_STORE_RECENT_DOCS
)
((type) == BOOKMARK_STORE_RECENT_APPS || (type) == BOOKMARK_STORE_RECENT_DOCS)
49
50typedef struct {
51 BookmarkStoreType type;
52
53 BookmarkItem **items;
54 gint n_items;
55 BookmarkStoreStatus status;
56
57 GBookmarkFile *store;
58 gboolean needs_sync;
59
60 gchar *store_path;
61 gchar *user_store_path;
62 gboolean user_modifiable;
63 gboolean reorderable;
64 const gchar *store_filename;
65
66 GFileMonitor *store_monitor;
67 GFileMonitor *user_store_monitor;
68
69 void (* update_path) (BookmarkAgent *);
70 void (* load_store) (BookmarkAgent *);
71 void (* save_store) (BookmarkAgent *);
72 void (* create_item) (BookmarkAgent *, const gchar *);
73
74 gchar *ctk_store_path;
75 GFileMonitor *ctk_store_monitor;
76} BookmarkAgentPrivate;
77
78enum {
79 PROP_0,
80 PROP_ITEMS,
81 PROP_STATUS
82};
83
84static BookmarkAgent *instances [BOOKMARK_STORE_N_TYPES];
85
86static BookmarkAgentClass *bookmark_agent_parent_class = NULL((void*)0);
87
88static void bookmark_agent_base_init (BookmarkAgentClass *);
89static void bookmark_agent_class_init (BookmarkAgentClass *);
90static void bookmark_agent_init (BookmarkAgent *);
91static BookmarkAgent *bookmark_agent_new (BookmarkStoreType );
92
93static void get_property (GObject *, guint, GValue *, GParamSpec *);
94static void set_property (GObject *, guint, const GValue *, GParamSpec *);
95static void finalize (GObject *);
96
97static void update_agent (BookmarkAgent *);
98static void update_items (BookmarkAgent *);
99static void save_store (BookmarkAgent *);
100static gint get_rank (BookmarkAgent *, const gchar *);
101static void set_rank (BookmarkAgent *, const gchar *, gint);
102
103static void load_xbel_store (BookmarkAgent *);
104static void load_places_store (BookmarkAgent *);
105static void update_user_spec_path (BookmarkAgent *);
106static void save_xbel_store (BookmarkAgent *);
107static void create_app_item (BookmarkAgent *, const gchar *);
108static void create_doc_item (BookmarkAgent *, const gchar *);
109static void create_dir_item (BookmarkAgent *, const gchar *);
110
111static void store_monitor_cb (GFileMonitor *, GFile *, GFile *,
112 GFileMonitorEvent, gpointer);
113static void weak_destroy_cb (gpointer, GObject *);
114
115static gint recent_item_mru_comp_func (gconstpointer a, gconstpointer b);
116
117static gchar *find_package_data_file (const gchar *filename);
118
119static gint BookmarkAgent_private_offset;
120
121static inline gpointer bookmark_agent_get_instance_private (BookmarkAgent *this)
122{
123 return (G_STRUCT_MEMBER_P (this, BookmarkAgent_private_offset)((gpointer) ((guint8*) (this) + (glong) (BookmarkAgent_private_offset
)))
);
124}
125
126GType
127bookmark_agent_get_type ()
128{
129 static GType g_define_type_id = 0;
130
131 if (G_UNLIKELY (g_define_type_id == 0)(g_define_type_id == 0)) {
132 static const GTypeInfo info = {
133 sizeof (BookmarkAgentClass),
134 (GBaseInitFunc) bookmark_agent_base_init,
135 NULL((void*)0),
136 (GClassInitFunc) bookmark_agent_class_init,
137 NULL((void*)0), NULL((void*)0),
138 sizeof (BookmarkAgent), 0,
139 (GInstanceInitFunc) bookmark_agent_init,
140 NULL((void*)0)
141 };
142
143 g_define_type_id = g_type_register_static (
144 G_TYPE_OBJECT((GType) ((20) << (2))), "BookmarkAgent", & info, 0);
145 G_ADD_PRIVATE (BookmarkAgent){ BookmarkAgent_private_offset = g_type_add_instance_private (
g_define_type_id, sizeof (BookmarkAgentPrivate)); }
;
146 }
147
148 return g_define_type_id;
149}
150
151BookmarkAgent *
152bookmark_agent_get_instance (BookmarkStoreType type)
153{
154 g_return_val_if_fail (0 <= type, NULL)do { if ((0 <= type)) { } else { g_return_if_fail_warning (
"libslab", ((const char*) (__func__)), "0 <= type"); return
(((void*)0)); } } while (0)
;
155 g_return_val_if_fail (type < BOOKMARK_STORE_N_TYPES, NULL)do { if ((type < BOOKMARK_STORE_N_TYPES)) { } else { g_return_if_fail_warning
("libslab", ((const char*) (__func__)), "type < BOOKMARK_STORE_N_TYPES"
); return (((void*)0)); } } while (0)
;
156
157 if (! instances [type]) {
158 instances [type] = bookmark_agent_new (type);
159 g_object_weak_ref (G_OBJECT (instances [type])((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((instances [type])), (((GType) ((20) << (2))))))))
, weak_destroy_cb, GINT_TO_POINTER (type)((gpointer) (glong) (type)));
160 }
161 else
162 g_object_ref (G_OBJECT (instances [type]))((__typeof__ (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((instances [type])), (((GType) ((20) <<
(2)))))))))) (g_object_ref) (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((instances [type])), (((GType) ((20) <<
(2))))))))))
;
163
164 return instances [type];
165}
166
167gboolean
168bookmark_agent_has_item (BookmarkAgent *this, const gchar *uri)
169{
170 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
171 return g_bookmark_file_has_item (priv->store, uri);
172}
173
174void
175bookmark_agent_add_item (BookmarkAgent *this, const BookmarkItem *item)
176{
177 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
178
179 if (! item)
180 return;
181
182 g_return_if_fail (priv->user_modifiable)do { if ((priv->user_modifiable)) { } else { g_return_if_fail_warning
("libslab", ((const char*) (__func__)), "priv->user_modifiable"
); return; } } while (0)
;
183 g_return_if_fail (item->uri)do { if ((item->uri)) { } else { g_return_if_fail_warning (
"libslab", ((const char*) (__func__)), "item->uri"); return
; } } while (0)
;
184 g_return_if_fail (item->mime_type)do { if ((item->mime_type)) { } else { g_return_if_fail_warning
("libslab", ((const char*) (__func__)), "item->mime_type"
); return; } } while (0)
;
185
186 g_bookmark_file_set_mime_type (priv->store, item->uri, item->mime_type);
187
188 if (item->mtime)
189 g_bookmark_file_set_modified (priv->store, item->uri, item->mtime);
190
191 if (item->title)
192 g_bookmark_file_set_title (priv->store, item->uri, item->title);
193
194 g_bookmark_file_add_application (priv->store, item->uri, item->app_name, item->app_exec);
195
196 set_rank (this, item->uri, g_bookmark_file_get_size (priv->store) - 1);
197
198 save_store (this);
199}
200
201void
202bookmark_agent_move_item (BookmarkAgent *this, const gchar *uri, const gchar *uri_new)
203{
204 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
205
206 GError *error = NULL((void*)0);
207
208 if (! TYPE_IS_RECENT (priv->type)((priv->type) == BOOKMARK_STORE_RECENT_APPS || (priv->type
) == BOOKMARK_STORE_RECENT_DOCS)
)
209 return;
210
211 ctk_recent_manager_move_item (ctk_recent_manager_get_default (), uri, uri_new, &error);
212 if (error) {
213 g_warning ("Unable to update %s with renamed file, [%s] -> [%s]: %s",
214 priv->store_path, uri, uri_new, error->message);
215 g_error_free (error);
216 }
217}
218
219void
220bookmark_agent_purge_items (BookmarkAgent *this)
221{
222 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
223
224 GError *error = NULL((void*)0);
225
226 gchar **uris = NULL((void*)0);
227 gsize uris_len;
228 gint i;
229 g_return_if_fail (priv->user_modifiable)do { if ((priv->user_modifiable)) { } else { g_return_if_fail_warning
("libslab", ((const char*) (__func__)), "priv->user_modifiable"
); return; } } while (0)
;
230
231 uris = g_bookmark_file_get_uris (priv->store, &uris_len);
232 if (TYPE_IS_RECENT (priv->type)((priv->type) == BOOKMARK_STORE_RECENT_APPS || (priv->type
) == BOOKMARK_STORE_RECENT_DOCS)
) {
233 for (i = 0; i < uris_len; i++) {
234 ctk_recent_manager_remove_item (ctk_recent_manager_get_default (), uris [i], &error);
235 if (error) {
236 g_warning ("Unable to remove [%s] from %s: %s",
237 priv->store_path, uris [i], error->message);
238 g_error_free (error);
239 }
240 }
241 } else {
242 for (i = 0; i < uris_len; i++) {
243 g_bookmark_file_remove_item (priv->store, uris [i], NULL((void*)0));
244 }
245 save_store (this);
246 }
247 g_strfreev (uris);
248}
249
250void
251bookmark_agent_remove_item (BookmarkAgent *this, const gchar *uri)
252{
253 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
254 gint rank;
255
256 GError *error = NULL((void*)0);
257
258 gchar **uris = NULL((void*)0);
259 gint rank_i;
260 gint i;
261
262
263 g_return_if_fail (priv->user_modifiable)do { if ((priv->user_modifiable)) { } else { g_return_if_fail_warning
("libslab", ((const char*) (__func__)), "priv->user_modifiable"
); return; } } while (0)
;
264
265 if (! bookmark_agent_has_item (this, uri))
266 return;
267
268 if (TYPE_IS_RECENT (priv->type)((priv->type) == BOOKMARK_STORE_RECENT_APPS || (priv->type
) == BOOKMARK_STORE_RECENT_DOCS)
) {
269 ctk_recent_manager_remove_item (ctk_recent_manager_get_default (), uri, &error);
270 if (error) {
271 g_warning ("Unable to remove [%s] from %s: %s", priv->store_path, uri, error->message);
272 g_error_free (error);
273 }
274 }
275 else {
276 rank = get_rank (this, uri);
277
278 g_bookmark_file_remove_item (priv->store, uri, NULL((void*)0));
279
280 if (rank >= 0) {
281 uris = g_bookmark_file_get_uris (priv->store, NULL((void*)0));
282
283 for (i = 0; uris && uris [i]; ++i) {
284 rank_i = get_rank (this, uris [i]);
285
286 if (rank_i > rank)
287 set_rank (this, uris [i], rank_i - 1);
288 }
289
290 g_strfreev (uris);
291 }
292
293 save_store (this);
294 }
295}
296
297void
298bookmark_agent_reorder_items (BookmarkAgent *this, const gchar **uris)
299{
300 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
301
302 gint i;
303
304
305 g_return_if_fail (priv->reorderable)do { if ((priv->reorderable)) { } else { g_return_if_fail_warning
("libslab", ((const char*) (__func__)), "priv->reorderable"
); return; } } while (0)
;
306
307 for (i = 0; uris && uris [i]; ++i)
308 set_rank (this, uris [i], i);
309
310 save_store (this);
311}
312
313static GList *
314make_items_from_bookmark_file (BookmarkAgent *this, GBookmarkFile *store)
315{
316 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
317 gchar **uris;
318 gint i;
319 GList *items_ordered;
320
321 if (!store)
322 return NULL((void*)0);
323
324 uris = g_bookmark_file_get_uris (store, NULL((void*)0));
325 items_ordered = NULL((void*)0);
326
327 for (i = 0; uris && uris [i]; ++i) {
328 gboolean include;
329
330 if (priv->type == BOOKMARK_STORE_RECENT_APPS)
331 include = g_bookmark_file_has_group (store, uris [i], "recently-used-apps", NULL((void*)0));
332 else
333 include = ! g_bookmark_file_get_is_private (store, uris [i], NULL((void*)0));
334
335 if (include) {
336 BookmarkItem *item;
337
338 item = g_new0 (BookmarkItem, 1)((BookmarkItem *) g_malloc0_n ((1), sizeof (BookmarkItem)));
339
340 item->uri = g_strdup (uris [i])g_strdup_inline (uris [i]);
341 item->mime_type = g_bookmark_file_get_mime_type (store, uris [i], NULL((void*)0));
342 item->mtime = g_bookmark_file_get_modified (store, uris [i], NULL((void*)0));
343
344 items_ordered = g_list_prepend (items_ordered, item);
345 }
346 }
347
348 items_ordered = g_list_sort (items_ordered, recent_item_mru_comp_func);
349
350 g_strfreev (uris);
351
352 return items_ordered;
353}
354
355void
356bookmark_agent_update_from_bookmark_file (BookmarkAgent *this, GBookmarkFile *store)
357{
358 BookmarkAgentPrivate *priv;
359 GList *items_ordered;
360 GList *node;
361
362 g_return_if_fail (IS_BOOKMARK_AGENT (this))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((this)); GType __t = ((bookmark_agent_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; })))))) { }
else { g_return_if_fail_warning ("libslab", ((const char*) (
__func__)), "IS_BOOKMARK_AGENT (this)"); return; } } while (0
)
;
363
364 priv = bookmark_agent_get_instance_private (this);
365
366 items_ordered = make_items_from_bookmark_file (this, store);
367
368 g_bookmark_file_free (priv->store);
369 priv->store = g_bookmark_file_new ();
370
371 for (node = items_ordered; node; node = node->next) {
372 BookmarkItem *item;
373
374 item = (BookmarkItem *) node->data;
375
376 g_bookmark_file_set_mime_type (priv->store, item->uri, item->mime_type);
377 g_bookmark_file_set_modified (priv->store, item->uri, item->mtime);
378
379 bookmark_item_free (item);
380 }
381
382 g_list_free (items_ordered);
383
384 update_items (this);
385}
386
387void
388bookmark_item_free (BookmarkItem *item)
389{
390 if (! item)
391 return;
392
393 g_free (item->uri);
394 g_free (item->title);
395 g_free (item->mime_type);
396 g_free (item->icon);
397 g_free (item->app_name);
398 g_free (item->app_exec);
399 g_free (item);
400}
401
402static void
403bookmark_agent_base_init (BookmarkAgentClass *this_class)
404{
405 gint i;
406
407 for (i = 0; i < BOOKMARK_STORE_N_TYPES; ++i)
408 instances [i] = NULL((void*)0);
409}
410
411static void
412bookmark_agent_class_init (BookmarkAgentClass *this_class)
413{
414 GObjectClass *g_obj_class = G_OBJECT_CLASS (this_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((this_class)), (((GType) ((20) << (2))))))))
;
415
416 GParamSpec *items_pspec;
417 GParamSpec *status_pspec;
418
419 if (BookmarkAgent_private_offset != 0)
420 g_type_class_adjust_private_offset (this_class, &BookmarkAgent_private_offset);
421
422 g_obj_class->get_property = get_property;
423 g_obj_class->set_property = set_property;
424 g_obj_class->finalize = finalize;
425
426 items_pspec = g_param_spec_pointer (
427 BOOKMARK_AGENT_ITEMS_PROP"items", BOOKMARK_AGENT_ITEMS_PROP"items",
428 "the null-terminated list which contains the bookmark items in this store",
429 G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
430
431 status_pspec = g_param_spec_int (
432 BOOKMARK_AGENT_STORE_STATUS_PROP"store-status", BOOKMARK_AGENT_STORE_STATUS_PROP"store-status", "the status of the store",
433 BOOKMARK_STORE_DEFAULT_ONLY, BOOKMARK_STORE_USER, BOOKMARK_STORE_DEFAULT,
434 G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
435
436 g_object_class_install_property (g_obj_class, PROP_ITEMS, items_pspec);
437 g_object_class_install_property (g_obj_class, PROP_STATUS, status_pspec);
438
439 bookmark_agent_parent_class = g_type_class_peek_parent (this_class);
440}
441
442static void
443bookmark_agent_init (BookmarkAgent *this)
444{
445 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
446
447 priv->type = -1;
448
449 priv->items = NULL((void*)0);
450 priv->n_items = 0;
451 priv->status = BOOKMARK_STORE_ABSENT;
452
453 priv->store = NULL((void*)0);
454 priv->needs_sync = FALSE(0);
455
456 priv->store_path = NULL((void*)0);
457 priv->user_store_path = NULL((void*)0);
458 priv->user_modifiable = FALSE(0);
459 priv->reorderable = FALSE(0);
460 priv->store_filename = NULL((void*)0);
461
462 priv->store_monitor = NULL((void*)0);
463 priv->user_store_monitor = NULL((void*)0);
464
465 priv->update_path = NULL((void*)0);
466 priv->load_store = NULL((void*)0);
467 priv->save_store = NULL((void*)0);
468 priv->create_item = NULL((void*)0);
469
470 priv->ctk_store_path = NULL((void*)0);
471 priv->ctk_store_monitor = NULL((void*)0);
472}
473
474static BookmarkAgent *
475bookmark_agent_new (BookmarkStoreType type)
476{
477 BookmarkAgent *this;
478 BookmarkAgentPrivate *priv;
479 GFile *ctk_store_file;
480
481 this = g_object_new (BOOKMARK_AGENT_TYPE(bookmark_agent_get_type ()), NULL((void*)0));
482 priv = bookmark_agent_get_instance_private (this);
483
484 priv->type = type;
485 priv->store = g_bookmark_file_new ();
486
487 switch (type) {
488 case BOOKMARK_STORE_USER_APPS:
489 priv->store_filename = USER_APPS_STORE_FILE_NAME"applications.xbel";
490 priv->create_item = create_app_item;
491
492 break;
493
494 case BOOKMARK_STORE_USER_DOCS:
495 priv->store_filename = USER_DOCS_STORE_FILE_NAME"documents.xbel";
496 priv->create_item = create_doc_item;
497
498 break;
499
500 case BOOKMARK_STORE_USER_DIRS:
501 priv->store_filename = USER_DIRS_STORE_FILE_NAME"places.xbel";
502 priv->create_item = create_dir_item;
503
504 priv->user_modifiable = TRUE(!(0));
505 priv->reorderable = FALSE(0);
506
507 priv->load_store = load_places_store;
508
509 priv->ctk_store_path = g_build_filename (g_get_user_config_dir (),
510 "ctk-3.0", CTK_BOOKMARKS_FILE"bookmarks", NULL((void*)0));
511 ctk_store_file = g_file_new_for_path (priv->ctk_store_path);
512 priv->ctk_store_monitor = g_file_monitor_file (ctk_store_file,
513 0, NULL((void*)0), NULL((void*)0));
514 if (priv->ctk_store_monitor) {
515 g_signal_connect (priv->ctk_store_monitor, "changed",g_signal_connect_data ((priv->ctk_store_monitor), ("changed"
), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags
) 0)
516 G_CALLBACK (store_monitor_cb), this)g_signal_connect_data ((priv->ctk_store_monitor), ("changed"
), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags
) 0)
;
517 }
518
519 g_object_unref (ctk_store_file);
520
521 break;
522
523 case BOOKMARK_STORE_RECENT_APPS:
524 case BOOKMARK_STORE_RECENT_DOCS:
525 priv->user_modifiable = TRUE(!(0));
526 priv->reorderable = FALSE(0);
527
528 priv->store_path = g_build_filename (g_get_user_data_dir (), "recently-used.xbel", NULL((void*)0));
529
530 break;
531
532 case BOOKMARK_STORE_SYSTEM:
533 priv->store_filename = SYSTEM_STORE_FILE_NAME"system-items.xbel";
534 priv->create_item = create_app_item;
535
536 break;
537
538 default:
539 break;
540 }
541
542 if (
543 type == BOOKMARK_STORE_USER_APPS || type == BOOKMARK_STORE_USER_DOCS ||
544 type == BOOKMARK_STORE_USER_DIRS || type == BOOKMARK_STORE_SYSTEM)
545 {
546 priv->user_modifiable = TRUE(!(0));
547
548 priv->user_store_path = g_build_filename (
549 g_get_user_data_dir (), PACKAGE"cafe-control-center", priv->store_filename, NULL((void*)0));
550
551 priv->update_path = update_user_spec_path;
552 }
553
554 if (type == BOOKMARK_STORE_USER_APPS || type == BOOKMARK_STORE_USER_DOCS || type == BOOKMARK_STORE_SYSTEM) {
555 priv->reorderable = TRUE(!(0));
556 priv->load_store = load_xbel_store;
557 priv->save_store = save_xbel_store;
558 }
559
560 update_agent (this);
561
562 return this;
563}
564
565static void
566get_property (GObject *g_obj, guint prop_id, GValue *value, GParamSpec *pspec)
567{
568 BookmarkAgent *this = BOOKMARK_AGENT (g_obj)((((BookmarkAgent*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_obj)), ((bookmark_agent_get_type ()))))))
;
569 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
570
571
572 switch (prop_id) {
573 case PROP_ITEMS:
574 g_value_set_pointer (value, priv->items);
575 break;
576
577 case PROP_STATUS:
578 g_value_set_int (value, priv->status);
579 break;
580 }
581}
582
583static void
584set_property (GObject *g_obj, guint prop_id, const GValue *value, GParamSpec *pspec)
585{
586 /* no writeable properties */
587}
588
589static void
590finalize (GObject *g_obj)
591{
592 BookmarkAgent *this = BOOKMARK_AGENT (g_obj)((((BookmarkAgent*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_obj)), ((bookmark_agent_get_type ()))))))
;
593 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
594
595 gint i;
596
597
598 for (i = 0; priv->items && priv->items [i]; ++i)
599 bookmark_item_free (priv->items [i]);
600
601 g_free (priv->items);
602 g_free (priv->store_path);
603 g_free (priv->user_store_path);
604 g_free (priv->ctk_store_path);
605
606 if (priv->store_monitor) {
607 g_signal_handlers_disconnect_by_func (priv->store_monitor, store_monitor_cb, this)g_signal_handlers_disconnect_matched ((priv->store_monitor
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (store_monitor_cb), (this))
;
608 g_file_monitor_cancel (priv->store_monitor);
609 g_object_unref (priv->store_monitor);
610 }
611
612 if (priv->user_store_monitor) {
613 g_signal_handlers_disconnect_by_func (priv->user_store_monitor, store_monitor_cb, this)g_signal_handlers_disconnect_matched ((priv->user_store_monitor
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (store_monitor_cb), (this))
;
614 g_file_monitor_cancel (priv->user_store_monitor);
615 g_object_unref (priv->user_store_monitor);
616 }
617
618 if (priv->ctk_store_monitor) {
619 g_signal_handlers_disconnect_by_func (priv->ctk_store_monitor, store_monitor_cb, this)g_signal_handlers_disconnect_matched ((priv->ctk_store_monitor
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (store_monitor_cb), (this))
;
620 g_file_monitor_cancel (priv->ctk_store_monitor);
621 g_object_unref (priv->ctk_store_monitor);
622 }
623
624 g_bookmark_file_free (priv->store);
625
626 G_OBJECT_CLASS (bookmark_agent_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((bookmark_agent_parent_class)), (((GType) ((20) << (
2))))))))
->finalize (g_obj);
627}
628
629static void
630update_agent (BookmarkAgent *this)
631{
632 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
633
634 if (priv->update_path)
2
Assuming field 'update_path' is null
3
Taking false branch
635 priv->update_path (this);
636
637 if (priv->load_store)
4
Assuming field 'load_store' is null
5
Taking false branch
638 priv->load_store (this);
639
640 update_items (this);
6
Calling 'update_items'
641}
642
643static void
644update_items (BookmarkAgent *this)
645{
646 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
647
648 gchar **uris = NULL((void*)0);
649 gchar **uris_ordered = NULL((void*)0);
650 gsize n_uris = 0;
651 gint rank = -1;
652 gint rank_corr = -1;
653 gboolean needs_update = FALSE(0);
654 gboolean store_corrupted = FALSE(0);
655 gchar *new_title, *old_title;
656
657 gint i;
658
659
660 uris = g_bookmark_file_get_uris (priv->store, & n_uris);
661 uris_ordered = g_new0 (gchar *, n_uris + 1)((gchar * *) g_malloc0_n ((n_uris + 1), sizeof (gchar *)));
662 uris_ordered [n_uris] = NULL((void*)0);
663
664 for (i = 0; uris
12.1
'uris' is non-null
&& uris [i]; ++i) {
7
Assuming 'uris' is non-null
8
Loop condition is true. Entering loop body
13
Loop condition is false. Execution continues on line 688
665 rank = get_rank (this, uris [i]);
666
667 if (rank
8.1
'rank' is < 0
< 0 || rank >= n_uris)
668 rank = i;
669
670 if (uris_ordered [rank]) {
9
Assuming the condition is true
10
Taking true branch
671 store_corrupted = TRUE(!(0));
672 rank_corr = rank;
673
674 for (rank = 0; rank < n_uris; ++rank)
11
Assuming 'rank' is >= 'n_uris'
12
Loop condition is false. Execution continues on line 678
675 if (! uris_ordered [rank])
676 break;
677
678 g_warning (
679 "store corruption [%s] - multiple uris with same rank (%d): [%s] [%s], moving latter to %d",
680 priv->store_path, rank_corr, uris_ordered [rank_corr], uris [i], rank);
681 }
682
683 set_rank (this, uris [i], rank);
684
685 uris_ordered [rank] = uris [i];
686 }
687
688 if (priv->n_items != n_uris)
14
Assuming 'n_uris' is equal to field 'n_items'
15
Taking false branch
689 needs_update = TRUE(!(0));
690
691 for (i = 0; ! needs_update
15.1
'needs_update' is 0
20.1
'needs_update' is 0
&& uris_ordered
15.2
'uris_ordered' is non-null
20.2
'uris_ordered' is non-null
&& uris_ordered [i]; ++i) {
16
Loop condition is true. Entering loop body
21
Out of bound memory access (access exceeds upper limit of memory block)
692 if (priv->type == BOOKMARK_STORE_USER_DIRS) {
17
Assuming field 'type' is not equal to BOOKMARK_STORE_USER_DIRS
18
Taking false branch
693 new_title = g_bookmark_file_get_title (priv->store, uris_ordered [i], NULL((void*)0));
694 old_title = priv->items [i]->title;
695 if (!new_title && !old_title) {
696 if (strcmp (priv->items [i]->uri, uris_ordered [i]))
697 needs_update = TRUE(!(0));
698 }
699 else if ((new_title && !old_title) || (!new_title && old_title))
700 needs_update = TRUE(!(0));
701 else if (strcmp (old_title, new_title))
702 needs_update = TRUE(!(0));
703 g_free (new_title);
704 }
705 else if (strcmp (priv->items [i]->uri, uris_ordered [i]))
19
Assuming the condition is false
20
Taking false branch
706 needs_update = TRUE(!(0));
707 }
708
709 if (needs_update) {
710 for (i = 0; priv->items && priv->items [i]; ++i)
711 bookmark_item_free (priv->items [i]);
712
713 g_free (priv->items);
714
715 priv->n_items = n_uris;
716 priv->items = g_new0 (BookmarkItem *, priv->n_items + 1)((BookmarkItem * *) g_malloc0_n ((priv->n_items + 1), sizeof
(BookmarkItem *)))
;
717
718 for (i = 0; uris_ordered && uris_ordered [i]; ++i) {
719 priv->items [i] = g_new0 (BookmarkItem, 1)((BookmarkItem *) g_malloc0_n ((1), sizeof (BookmarkItem)));
720 priv->items [i]->uri = g_strdup (uris_ordered [i])g_strdup_inline (uris_ordered [i]);
721 priv->items [i]->title = g_bookmark_file_get_title (priv->store, uris_ordered [i], NULL((void*)0));
722 priv->items [i]->mime_type = g_bookmark_file_get_mime_type (priv->store, uris_ordered [i], NULL((void*)0));
723 priv->items [i]->mtime = g_bookmark_file_get_modified (priv->store, uris_ordered [i], NULL((void*)0));
724 priv->items [i]->app_name = NULL((void*)0);
725 priv->items [i]->app_exec = NULL((void*)0);
726
727 g_bookmark_file_get_icon (priv->store, uris_ordered [i], & priv->items [i]->icon, NULL((void*)0), NULL((void*)0));
728 }
729
730 /* Since the bookmark store for recently-used items is updated by the caller of BookmarkAgent,
731 * we don't emit notifications in that case. The caller will know when to update itself.
732 */
733 if (!TYPE_IS_RECENT (priv->type)((priv->type) == BOOKMARK_STORE_RECENT_APPS || (priv->type
) == BOOKMARK_STORE_RECENT_DOCS)
)
734 g_object_notify (G_OBJECT (this)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((this)), (((GType) ((20) << (2))))))))
, BOOKMARK_AGENT_ITEMS_PROP"items");
735 }
736
737 if (store_corrupted)
738 save_store (this);
739
740 g_strfreev (uris);
741 g_free (uris_ordered);
742}
743
744static void
745save_store (BookmarkAgent *this)
746{
747 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
748
749 gchar *dir;
750
751
752 g_return_if_fail (priv->user_modifiable)do { if ((priv->user_modifiable)) { } else { g_return_if_fail_warning
("libslab", ((const char*) (__func__)), "priv->user_modifiable"
); return; } } while (0)
;
753
754 priv->needs_sync = TRUE(!(0));
755 priv->update_path (this);
756
757 dir = g_path_get_dirname (priv->store_path);
758 g_mkdir_with_parents (dir, 0700);
759 g_free (dir);
760
761 priv->save_store (this);
762 update_items (this);
763}
764
765static gint
766get_rank (BookmarkAgent *this, const gchar *uri)
767{
768 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
769
770 gchar **groups;
771 gint rank;
772
773 gint i;
774
775
776 if (! priv->reorderable)
777 return -1;
778
779 groups = g_bookmark_file_get_groups (priv->store, uri, NULL((void*)0), NULL((void*)0));
780 rank = -1;
781
782 for (i = 0; groups && groups [i]; ++i) {
783 if (g_str_has_prefix (groups [i], "rank-")(__builtin_constant_p ("rank-")? __extension__ ({ const char *
const __str = (groups [i]); const char * const __prefix = ("rank-"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (groups [i], "rank-") )
) {
784 if (rank >= 0)
785 g_warning (
786 "store corruption - multiple ranks for same uri: [%s] [%s]",
787 priv->store_path, uri);
788
789 rank = atoi (& groups [i] [5]);
790 }
791 }
792
793 g_strfreev (groups);
794
795 return rank;
796}
797
798static void
799set_rank (BookmarkAgent *this, const gchar *uri, gint rank)
800{
801 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
802
803 gchar **groups;
804 gchar *group;
805
806 gint i;
807
808
809 if (! (priv->reorderable && bookmark_agent_has_item (this, uri)))
810 return;
811
812 groups = g_bookmark_file_get_groups (priv->store, uri, NULL((void*)0), NULL((void*)0));
813
814 for (i = 0; groups && groups [i]; ++i)
815 if (g_str_has_prefix (groups [i], "rank-")(__builtin_constant_p ("rank-")? __extension__ ({ const char *
const __str = (groups [i]); const char * const __prefix = ("rank-"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (groups [i], "rank-") )
)
816 g_bookmark_file_remove_group (priv->store, uri, groups [i], NULL((void*)0));
817
818 g_strfreev (groups);
819
820 group = g_strdup_printf ("rank-%d", rank);
821 g_bookmark_file_add_group (priv->store, uri, group);
822 g_free (group);
823}
824
825static void
826load_xbel_store (BookmarkAgent *this)
827{
828 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
829
830 gchar **uris = NULL((void*)0);
831
832 GError *error = NULL((void*)0);
833
834 gint i;
835 gboolean success;
836
837 if (!priv->store_path)
838 success = FALSE(0);
839 else {
840 success = g_bookmark_file_load_from_file (priv->store, priv->store_path, & error);
841 }
842
843 if (!success) {
844 g_bookmark_file_free (priv->store);
845 priv->store = g_bookmark_file_new ();
846
847 if (error) {
848 g_debug ("Couldn't load bookmark file [%s]: %s", priv->store_path, error->message);
849 g_error_free (error);
850 } else {
851 g_debug ("Couldn't load bookmark file [NULL]");
852 }
853 return;
854 }
855
856 uris = g_bookmark_file_get_uris (priv->store, NULL((void*)0));
857
858 for (i = 0; uris && uris [i]; ++i)
859 priv->create_item (this, uris [i]);
860
861 g_strfreev (uris);
862}
863
864static void
865load_places_store (BookmarkAgent *this)
866{
867 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
868
869 gchar **uris;
870 gchar **groups;
871 gchar **bookmarks = NULL((void*)0);
872
873 gchar *buf, *label, *uri;
874
875 gint i, j, bookmark_len;
876
877 load_xbel_store (this);
878
879 uris = g_bookmark_file_get_uris (priv->store, NULL((void*)0));
880
881 for (i = 0; uris && uris [i]; ++i) {
882 groups = g_bookmark_file_get_groups (priv->store, uris [i], NULL((void*)0), NULL((void*)0));
883
884 for (j = 0; groups && groups [j]; ++j) {
885 if (! strcmp (groups [j], "ctk-bookmarks")) {
886 g_bookmark_file_remove_item (priv->store, uris [i], NULL((void*)0));
887
888 break;
889 }
890 }
891
892 g_strfreev (groups);
893 }
894
895 g_strfreev (uris);
896
897 g_file_get_contents (priv->ctk_store_path, & buf, NULL((void*)0), NULL((void*)0));
898
899 if (buf) {
900 bookmarks = g_strsplit (buf, "\n", -1);
901 g_free (buf);
902 }
903
904 for (i = 0; bookmarks && bookmarks [i]; ++i) {
905 bookmark_len = strlen (bookmarks [i]);
906 if (bookmark_len > 0) {
907 label = strstr (bookmarks[i], " ");
908 if (label != NULL((void*)0))
909 uri = g_strndup (bookmarks [i], bookmark_len - strlen (label));
910 else
911 uri = bookmarks [i];
912 g_bookmark_file_add_group (priv->store, uri, "ctk-bookmarks");
913 priv->create_item (this, uri);
914 if (label != NULL((void*)0)) {
915 label++;
916 if (strlen (label) > 0)
917 g_bookmark_file_set_title (priv->store, uri, label);
918 g_free (uri);
919 }
920 }
921 }
922
923 g_strfreev (bookmarks);
924}
925
926static gchar *
927find_package_data_file (const gchar *filename)
928{
929 const gchar * const *dirs = NULL((void*)0);
930 gchar *path = NULL((void*)0);
931 gint i;
932
933
934 dirs = g_get_system_data_dirs ();
935
936 for (i = 0; ! path && dirs && dirs [i]; ++i) {
937 path = g_build_filename (dirs [i], PACKAGE"cafe-control-center", filename, NULL((void*)0));
938
939 if (! g_file_test (path, G_FILE_TEST_EXISTS)) {
940 g_free (path);
941 path = NULL((void*)0);
942 }
943 }
944
945 return path;
946}
947
948static void
949update_user_spec_path (BookmarkAgent *this)
950{
951 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
952
953 gboolean use_user_path;
954 gchar *path = NULL((void*)0);
955
956 BookmarkStoreStatus status;
957
958 use_user_path = priv->user_modifiable &&
959 (priv->needs_sync || g_file_test (priv->user_store_path, G_FILE_TEST_EXISTS));
960
961 if (use_user_path)
962 path = g_strdup (priv->user_store_path)g_strdup_inline (priv->user_store_path);
963 else
964 path = find_package_data_file (priv->store_filename);
965
966 if (use_user_path)
967 status = BOOKMARK_STORE_USER;
968 else if (path && priv->user_modifiable)
969 status = BOOKMARK_STORE_DEFAULT;
970 else if (path)
971 status = BOOKMARK_STORE_DEFAULT_ONLY;
972 else
973 status = BOOKMARK_STORE_ABSENT;
974
975 if (priv->status != status) {
976 priv->status = status;
977 g_object_notify (G_OBJECT (this)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((this)), (((GType) ((20) << (2))))))))
, BOOKMARK_AGENT_STORE_STATUS_PROP"store-status");
978
979 if (priv->user_store_monitor) {
980 g_file_monitor_cancel (priv->user_store_monitor);
981 g_object_unref (priv->user_store_monitor);
982 priv->user_store_monitor = NULL((void*)0);
983 }
984
985 if (priv->status == BOOKMARK_STORE_DEFAULT) {
986 GFile *user_store_file;
987
988 user_store_file = g_file_new_for_path (priv->user_store_path);
989 priv->user_store_monitor = g_file_monitor_file (user_store_file,
990 0, NULL((void*)0), NULL((void*)0));
991 if (priv->user_store_monitor) {
992 g_signal_connect (priv->user_store_monitor, "changed",g_signal_connect_data ((priv->user_store_monitor), ("changed"
), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags
) 0)
993 G_CALLBACK (store_monitor_cb), this)g_signal_connect_data ((priv->user_store_monitor), ("changed"
), (((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags
) 0)
;
994 }
995
996 g_object_unref (user_store_file);
997 }
998 }
999
1000 if (libslab_strcmp (priv->store_path, path)) {
1001 g_free (priv->store_path);
1002 priv->store_path = path;
1003
1004 if (priv->store_monitor) {
1005 g_file_monitor_cancel (priv->store_monitor);
1006 g_object_unref (priv->store_monitor);
1007 }
1008
1009 if (priv->store_path) {
1010 GFile *store_file;
1011
1012 store_file = g_file_new_for_path (priv->store_path);
1013 priv->store_monitor = g_file_monitor_file (store_file,
1014 0, NULL((void*)0), NULL((void*)0));
1015 if (priv->store_monitor) {
1016 g_signal_connect (priv->store_monitor, "changed",g_signal_connect_data ((priv->store_monitor), ("changed"),
(((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags
) 0)
1017 G_CALLBACK (store_monitor_cb), this)g_signal_connect_data ((priv->store_monitor), ("changed"),
(((GCallback) (store_monitor_cb))), (this), ((void*)0), (GConnectFlags
) 0)
;
1018 }
1019
1020 g_object_unref (store_file);
1021 }
1022 }
1023 else
1024 g_free (path);
1025}
1026
1027static void
1028save_xbel_store (BookmarkAgent *this)
1029{
1030 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
1031
1032 GError *error = NULL((void*)0);
1033
1034 if (g_bookmark_file_to_file (priv->store, priv->store_path, &error))
1035 return;
1036
1037 if (error) {
1038 g_warning ("Couldn't save bookmark file [%s]: %s", priv->store_path, error->message);
1039 g_error_free (error);
1040 } else {
1041 g_warning ("Couldn't save bookmark file [%s]", priv->store_path);
1042 }
1043}
1044
1045static void
1046create_app_item (BookmarkAgent *this, const gchar *uri)
1047{
1048 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
1049
1050 CafeDesktopItem *ditem;
1051 gchar *uri_new = NULL((void*)0);
1052
1053 ditem = libslab_cafe_desktop_item_new_from_unknown_id (uri);
1054
1055 if (ditem) {
1056 uri_new = g_strdup (cafe_desktop_item_get_location (ditem))g_strdup_inline (cafe_desktop_item_get_location (ditem));
1057 cafe_desktop_item_unref (ditem);
1058 }
1059
1060 if (! uri_new)
1061 return;
1062
1063 if (libslab_strcmp (uri, uri_new))
1064 g_bookmark_file_move_item (priv->store, uri, uri_new, NULL((void*)0));
1065
1066 g_free (uri_new);
1067}
1068
1069static void
1070create_doc_item (BookmarkAgent *this, const gchar *uri)
1071{
1072 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
1073
1074 gchar *uri_new = NULL((void*)0);
1075
1076 if ((strcmp (uri, "BLANK_SPREADSHEET") == 0) || (strcmp (uri, "BLANK_DOCUMENT") == 0)) {
1077 gchar *template = NULL((void*)0);
1078 gchar *file;
1079
1080 gchar *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS))g_strdup_inline (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS
))
;
1081 if (!dir)
1082 dir = g_build_filename (g_get_home_dir (), "Documents", NULL((void*)0));
1083
1084 if (strcmp (uri, "BLANK_SPREADSHEET") == 0) {
1085 g_bookmark_file_set_title (priv->store, uri, "BLANK_SPREADSHEET");
1086 file = g_strconcat (_("New Spreadsheet")((char *) g_dgettext ("cafe-control-center", "New Spreadsheet"
))
, ".ots", NULL((void*)0));
1087 template = find_package_data_file (CALC_TEMPLATE_FILE_NAME"empty.ots");
1088 } else {
1089 g_bookmark_file_set_title (priv->store, uri, "BLANK_DOCUMENT");
1090 file = g_strconcat (_("New Document")((char *) g_dgettext ("cafe-control-center", "New Document")), ".ott", NULL((void*)0));
1091 template = find_package_data_file (WRITER_TEMPLATE_FILE_NAME"empty.ott");
1092 }
1093
1094 gchar *path = g_build_filename (dir, file, NULL((void*)0));
1095 if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
1096 g_mkdir_with_parents (dir, 0700);
1097
1098 if (template != NULL((void*)0)) {
1099 gchar *contents;
1100 gsize length;
1101
1102 if (g_file_get_contents (template, &contents, &length, NULL((void*)0)))
1103 g_file_set_contents (path, contents, length, NULL((void*)0));
1104
1105 g_free (contents);
1106 } else {
1107 fclose (g_fopenfopen (path, "w"));
1108 }
1109 }
1110
1111 uri_new = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0));
1112
1113 g_free (dir);
1114 g_free (file);
1115 g_free (path);
1116 g_free (template);
1117 }
1118
1119 if (!uri_new)
1120 return;
1121
1122 if (libslab_strcmp (uri, uri_new))
1123 g_bookmark_file_move_item (priv->store, uri, uri_new, NULL((void*)0));
1124
1125 g_free (uri_new);
1126}
1127
1128static void
1129create_dir_item (BookmarkAgent *this, const gchar *uri)
1130{
1131 BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this);
1132
1133 gchar *uri_new = NULL((void*)0);
1134 gchar *path = NULL((void*)0);
1135 gchar *name = NULL((void*)0);
1136 gchar *icon = NULL((void*)0);
1137
1138 gchar *search_string = NULL((void*)0);
1139
1140 gboolean gotta_free_name = FALSE(0);
1141
1142 if (strcmp (uri, "HOME") == 0) {
1143 uri_new = g_filename_to_uri (g_get_home_dir (), NULL((void*)0), NULL((void*)0));
1144 name = g_strdup (C_("Home folder", "Home"))g_strdup_inline (g_dpgettext ("cafe-control-center", "Home folder"
"\004" "Home", strlen ("Home folder") + 1))
;
1145 gotta_free_name = TRUE(!(0));
1146 icon = "user-home";
1147 } else if (strcmp (uri, "DOCUMENTS") == 0) {
1148 path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS))g_strdup_inline (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS
))
;
1149 if (!path)
1150 path = g_build_filename (g_get_home_dir (), "Documents", NULL((void*)0));
1151 name = _("Documents")((char *) g_dgettext ("cafe-control-center", "Documents"));
1152 uri_new = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0));
1153 } else if (strcmp (uri, "DESKTOP") == 0) {
1154 path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP))g_strdup_inline (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP
))
;
1155 if (!path)
1156 path = g_build_filename (g_get_home_dir (), "Desktop", NULL((void*)0));
1157 name = _("Desktop")((char *) g_dgettext ("cafe-control-center", "Desktop"));
1158 uri_new = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0));
1159 icon = "user-desktop";
1160 } else if (strcmp (uri, "file:///") == 0) {
1161 icon = "drive-harddisk";
1162 name = _("File System")((char *) g_dgettext ("cafe-control-center", "File System"));
1163 } else if (strcmp (uri, "network:") == 0) {
1164 icon = "network-workgroup";
1165 name = _("Network Servers")((char *) g_dgettext ("cafe-control-center", "Network Servers"
))
;
1166 } else if (g_str_has_prefix (uri, "x-baul-search")(__builtin_constant_p ("x-baul-search")? __extension__ ({ const
char * const __str = (uri); const char * const __prefix = ("x-baul-search"
); gboolean __result = (0); if (__str == ((void*)0) || __prefix
== ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix
))); if (__str_len >= __prefix_len) __result = memcmp (((__str
) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0
; } __result; }) : (g_str_has_prefix) (uri, "x-baul-search") )
) {
1167 icon = "system-search";
1168
1169 path = g_build_filename (g_get_user_data_dir (), "baul", "searches", & uri [21], NULL((void*)0));
1170
1171 if (g_file_test (path, G_FILE_TEST_EXISTS)) {
1172 gchar *buf = NULL((void*)0);
1173 g_file_get_contents (path, &buf, NULL((void*)0), NULL((void*)0));
1174
1175 gchar *tag_open_ptr = NULL((void*)0);
1176 gchar *tag_close_ptr = NULL((void*)0);
1177
1178 if (buf) {
1179 tag_open_ptr = strstr (buf, "<text>");
1180 tag_close_ptr = strstr (buf, "</text>");
1181 }
1182
1183 if (tag_open_ptr && tag_close_ptr) {
1184 tag_close_ptr [0] = '\0';
1185 tag_close_ptr [0] = 'a';
1186 search_string = g_strdup_printf ("\"%s\"", &tag_open_ptr[6]);
1187 }
1188
1189 g_free (buf);
1190 }
1191
1192 if (search_string) {
1193 name = search_string;
1194 gotta_free_name = TRUE(!(0));
1195 } else {
1196 name = _("Search")((char *) g_dgettext ("cafe-control-center", "Search"));
1197 }
1198 }
1199
1200 if (icon)
1201 g_bookmark_file_set_icon (priv->store, uri, icon, "image/png");
1202
1203 if (name)
1204 g_bookmark_file_set_title (priv->store, uri, name);
1205
1206 if (uri_new && libslab_strcmp (uri, uri_new))
1207 g_bookmark_file_move_item (priv->store, uri, uri_new, NULL((void*)0));
1208
1209 if (gotta_free_name) {
1210 g_free (name);
1211 }
1212
1213 g_free (path);
1214 g_free (uri_new);
1215}
1216
1217static void
1218store_monitor_cb (GFileMonitor *mon, GFile *f1, GFile *f2,
1219 GFileMonitorEvent event_type, gpointer user_data)
1220{
1221 update_agent (BOOKMARK_AGENT (user_data)((((BookmarkAgent*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((user_data)), ((bookmark_agent_get_type ()))))))
)
;
1
Calling 'update_agent'
1222}
1223
1224static void
1225weak_destroy_cb (gpointer data, GObject *g_obj)
1226{
1227 instances [GPOINTER_TO_INT (data)((gint) (glong) (data))] = NULL((void*)0);
1228}
1229
1230static gint
1231recent_item_mru_comp_func (gconstpointer a, gconstpointer b)
1232{
1233 return ((BookmarkItem *) b)->mtime - ((BookmarkItem *) a)->mtime;
1234}