/src/tinysparql/src/common/tracker-file-utils.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2006, Jamie McCracken <jamiemcc@gnome.org> |
3 | | * Copyright (C) 2008, Nokia <ivan.frade@nokia.com> |
4 | | * |
5 | | * This library is free software; you can redistribute it and/or |
6 | | * modify it under the terms of the GNU Lesser General Public |
7 | | * License as published by the Free Software Foundation; either |
8 | | * version 2.1 of the License, or (at your option) any later version. |
9 | | * |
10 | | * This library is distributed in the hope that it will be useful, |
11 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | | * Lesser General Public License for more details. |
14 | | * |
15 | | * You should have received a copy of the GNU Lesser General Public |
16 | | * License along with this library; if not, write to the |
17 | | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | | * Boston, MA 02110-1301, USA. |
19 | | */ |
20 | | |
21 | | #include "config.h" |
22 | | |
23 | | #include <string.h> |
24 | | #include <unistd.h> |
25 | | #include <sys/types.h> |
26 | | #include <sys/stat.h> |
27 | | #include <sys/statvfs.h> |
28 | | #include <sys/file.h> |
29 | | #include <fcntl.h> |
30 | | #include <limits.h> |
31 | | #include <errno.h> |
32 | | |
33 | | #ifdef __linux__ |
34 | | #include <sys/statfs.h> |
35 | | #endif |
36 | | |
37 | | #include <glib.h> |
38 | | #include <glib/gstdio.h> |
39 | | #include <gio/gio.h> |
40 | | |
41 | | #include "tracker-file-utils.h" |
42 | | |
43 | | #define TEXT_SNIFF_SIZE 4096 |
44 | | |
45 | | goffset |
46 | | tracker_file_get_size (const gchar *path) |
47 | 0 | { |
48 | 0 | GFileInfo *info; |
49 | 0 | GFile *file; |
50 | 0 | GError *error = NULL; |
51 | 0 | goffset size; |
52 | |
|
53 | 0 | g_return_val_if_fail (path != NULL, 0); |
54 | | |
55 | 0 | file = g_file_new_for_path (path); |
56 | 0 | info = g_file_query_info (file, |
57 | 0 | G_FILE_ATTRIBUTE_STANDARD_SIZE, |
58 | 0 | G_FILE_QUERY_INFO_NONE, |
59 | 0 | NULL, |
60 | 0 | &error); |
61 | |
|
62 | 0 | if (G_UNLIKELY (error)) { |
63 | 0 | gchar *uri; |
64 | |
|
65 | 0 | uri = g_file_get_uri (file); |
66 | 0 | g_message ("Could not get size for '%s', %s", |
67 | 0 | uri, |
68 | 0 | error->message); |
69 | 0 | g_free (uri); |
70 | 0 | g_error_free (error); |
71 | 0 | size = 0; |
72 | 0 | } else { |
73 | 0 | size = g_file_info_get_size (info); |
74 | 0 | g_object_unref (info); |
75 | 0 | } |
76 | |
|
77 | 0 | g_object_unref (file); |
78 | |
|
79 | 0 | return size; |
80 | 0 | } |
81 | | |
82 | | #ifdef __linux__ |
83 | | |
84 | 0 | #define __bsize f_bsize |
85 | | |
86 | | #ifdef __USE_LARGEFILE64 |
87 | 0 | #define __statvfs statfs64 |
88 | | #else |
89 | | #define __statvfs statfs |
90 | | #endif |
91 | | |
92 | | #else /* __linux__ */ |
93 | | |
94 | | #define __bsize f_frsize |
95 | | |
96 | | #ifdef HAVE_STATVFS64 |
97 | | #define __statvfs statvfs64 |
98 | | #else |
99 | | #define __statvfs statvfs |
100 | | #endif |
101 | | |
102 | | #endif /* __linux__ */ |
103 | | |
104 | | static gboolean |
105 | | statvfs_helper (const gchar *path, struct __statvfs *st) |
106 | 0 | { |
107 | 0 | gchar *_path; |
108 | 0 | int retval; |
109 | | |
110 | | //LCOV_EXCL_START |
111 | | /* Iterate up the path to the root until statvfs() doesn’t error with |
112 | | * ENOENT. This prevents the call failing on first-startup when (for |
113 | | * example) ~/.cache/tracker might not exist. */ |
114 | 0 | _path = g_strdup (path); |
115 | |
|
116 | 0 | while ((retval = __statvfs (_path, st)) == -1 && errno == ENOENT) { |
117 | 0 | gchar *tmp = g_path_get_dirname (_path); |
118 | 0 | g_free (_path); |
119 | 0 | _path = tmp; |
120 | 0 | } |
121 | |
|
122 | 0 | g_free (_path); |
123 | | //LCOV_EXCL_STOP |
124 | |
|
125 | 0 | if (retval == -1) { |
126 | 0 | g_critical ("Could not statvfs() '%s': %s", |
127 | 0 | path, |
128 | 0 | g_strerror (errno)); |
129 | 0 | } |
130 | |
|
131 | 0 | return (retval == 0); |
132 | 0 | } |
133 | | |
134 | | static guint64 |
135 | | tracker_file_system_get_remaining_space (const gchar *path) |
136 | 0 | { |
137 | 0 | struct __statvfs st; |
138 | 0 | guint64 available; |
139 | |
|
140 | 0 | if (statvfs_helper (path, &st)) { |
141 | 0 | available = (geteuid () == 0) ? st.f_bfree : st.f_bavail; |
142 | | /* __bsize is a platform dependent #define above */ |
143 | 0 | return st.__bsize * available; |
144 | 0 | } else { |
145 | 0 | return 0; |
146 | 0 | } |
147 | 0 | } |
148 | | |
149 | | gboolean |
150 | | tracker_file_system_has_enough_space (const gchar *path, |
151 | | gulong required_bytes, |
152 | | gboolean creating_db) |
153 | 0 | { |
154 | 0 | gchar *str1; |
155 | 0 | gchar *str2; |
156 | 0 | gboolean enough; |
157 | 0 | guint64 remaining; |
158 | |
|
159 | 0 | g_return_val_if_fail (path != NULL, FALSE); |
160 | | |
161 | 0 | remaining = tracker_file_system_get_remaining_space (path); |
162 | 0 | enough = (remaining >= required_bytes); |
163 | |
|
164 | 0 | if (creating_db) { |
165 | 0 | str1 = g_format_size (required_bytes); |
166 | 0 | str2 = g_format_size (remaining); |
167 | |
|
168 | 0 | if (!enough) { |
169 | 0 | g_critical ("Not enough disk space to create databases, " |
170 | 0 | "%s remaining, %s required as a minimum", |
171 | 0 | str2, |
172 | 0 | str1); |
173 | 0 | } else { |
174 | 0 | g_debug ("Checking for adequate disk space to create databases, " |
175 | 0 | "%s remaining, %s required as a minimum", |
176 | 0 | str2, |
177 | 0 | str1); |
178 | 0 | } |
179 | |
|
180 | 0 | g_free (str2); |
181 | 0 | g_free (str1); |
182 | 0 | } |
183 | |
|
184 | 0 | return enough; |
185 | 0 | } |