Branch data Line data Source code
1 : : /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 : : /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 : : /*
4 : : * This file is part of libaccounts-glib
5 : : *
6 : : * Copyright (C) 2011 Nokia Corporation.
7 : : *
8 : : * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
9 : : *
10 : : * This library is free software; you can redistribute it and/or
11 : : * modify it under the terms of the GNU Lesser General Public License
12 : : * version 2.1 as published by the Free Software Foundation.
13 : : *
14 : : * This library is distributed in the hope that it will be useful, but
15 : : * WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : * Lesser General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU Lesser General Public
20 : : * License along with this library; if not, write to the Free Software
21 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 : : * 02110-1301 USA
23 : : */
24 : :
25 : : #include <glib.h>
26 : : #include <sched.h>
27 : : #include <sqlite3.h>
28 : : #include <stdio.h>
29 : : #include <stdlib.h>
30 : : #include <string.h>
31 : :
32 : : static void
33 : 0 : show_help ()
34 : : {
35 : 0 : printf ("\nUsage:\n"
36 : : " %1$s\n"
37 : : "Backups the accounts from ~/.config/libaccounts-glib/accounts.db\n"
38 : : "into ~/.config/libaccounts-glib/accounts.db.bak\n\n",
39 : : g_get_prgname());
40 : 0 : }
41 : :
42 : : static gboolean
43 : 0 : write_backup (sqlite3 *src, const gchar *filename)
44 : : {
45 : : sqlite3_backup *backup;
46 : : sqlite3 *dest;
47 : : gint n_retries;
48 : : int ret;
49 : :
50 : 0 : ret = sqlite3_open (filename, &dest);
51 : 0 : if (ret != SQLITE_OK) return FALSE;
52 : :
53 : 0 : backup = sqlite3_backup_init (dest, "main", src, "main");
54 : 0 : if (!backup)
55 : : {
56 : 0 : g_warning ("Couldn't start backup");
57 : 0 : sqlite3_close (dest);
58 : 0 : return FALSE;
59 : : }
60 : :
61 : 0 : n_retries = 0;
62 : : do
63 : : {
64 : 0 : ret = sqlite3_backup_step (backup, -1);
65 : 0 : if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
66 : 0 : sqlite3_sleep(250);
67 : 0 : n_retries++;
68 : : }
69 : 0 : while ((ret == SQLITE_BUSY || ret == SQLITE_LOCKED) && n_retries < 5);
70 : :
71 : 0 : sqlite3_backup_finish (backup);
72 : :
73 : 0 : sqlite3_close (dest);
74 : 0 : return ret == SQLITE_OK;
75 : : }
76 : :
77 : : static gboolean
78 : 0 : backup ()
79 : : {
80 : : gchar *filename, *filename_bak;
81 : : sqlite3 *db;
82 : : gint n_retries;
83 : : int ret;
84 : 0 : gboolean success = FALSE;;
85 : :
86 : 0 : filename = g_build_filename (g_get_user_config_dir (),
87 : : DATABASE_DIR,
88 : : "accounts.db",
89 : : NULL);
90 : 0 : filename_bak = g_strdup_printf ("%s.bak", filename);
91 : :
92 : 0 : g_debug ("Opening %s", filename);
93 : :
94 : 0 : n_retries = 0;
95 : : do
96 : : {
97 : 0 : ret = sqlite3_open (filename, &db);
98 : 0 : if (ret == SQLITE_BUSY)
99 : 0 : sched_yield ();
100 : 0 : n_retries++;
101 : : }
102 : 0 : while (ret == SQLITE_BUSY && n_retries < 5);
103 : :
104 : 0 : if (G_UNLIKELY (ret != SQLITE_OK))
105 : : {
106 : 0 : g_warning ("Couldn't open accounts DB: %s", sqlite3_errmsg (db));
107 : 0 : goto error_open;
108 : : }
109 : :
110 : 0 : n_retries = 0;
111 : : do
112 : : {
113 : 0 : ret = sqlite3_wal_checkpoint (db, NULL);
114 : 0 : if (ret == SQLITE_BUSY)
115 : 0 : sched_yield ();
116 : 0 : n_retries++;
117 : : }
118 : 0 : while (ret == SQLITE_BUSY && n_retries < 5);
119 : :
120 : 0 : if (G_UNLIKELY (ret != SQLITE_OK))
121 : 0 : g_warning ("Checkpoint failed: %s", sqlite3_errmsg (db));
122 : :
123 : 0 : success = write_backup (db, filename_bak);
124 : :
125 : 0 : sqlite3_close (db);
126 : 0 : success = TRUE;
127 : :
128 : : error_open:
129 : 0 : g_free (filename_bak);
130 : 0 : g_free (filename);
131 : 0 : return success;
132 : : }
133 : :
134 : : int
135 : 0 : main (int argc, char **argv)
136 : : {
137 : : gboolean success;
138 : :
139 : 0 : g_set_prgname (g_path_get_basename (argv[0]));
140 : :
141 : 0 : if (argc > 1)
142 : : {
143 : 0 : show_help ();
144 : 0 : return 0;
145 : : }
146 : :
147 : 0 : success = backup ();
148 : :
149 : 0 : return success ? EXIT_SUCCESS : EXIT_FAILURE;
150 : : }
151 : :
|