Bug Summary

File:src/camel/providers/local/camel-maildir-store.c
Warning:line 1308, column 14
File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -O3 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name camel-maildir-store.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=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/GNOME/evolution-data-server/_build -fcoverage-compilation-dir=/builds/GNOME/evolution-data-server/_build -resource-dir /usr/bin/../lib/clang/22 -D GLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_68 -D GLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_68 -D G_LOG_DOMAIN="camel-local-provider" -D LDAP_DEPRECATED -D SOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_3_2 -D SOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_3_2 -D _LARGEFILE64_SOURCE=1 -D camellocal_EXPORTS -I /builds/GNOME/evolution-data-server/_build -I /builds/GNOME/evolution-data-server/_build/src -I /builds/GNOME/evolution-data-server/_build/src/camel -I /builds/GNOME/evolution-data-server/src -I /builds/GNOME/evolution-data-server/src/camel -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/nss3 -I /usr/include/nspr4 -D NDEBUG -I /usr/include -D WITH_GZFILEOP -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/nss3 -I /usr/include/nspr4 -internal-isystem /usr/bin/../lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -Wno-sign-compare -Wno-missing-field-initializers -Wno-missing-include-dirs -Wno-deprecated-declarations -Wno-cast-function-type -Wwrite-strings -fconst-strings -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/GNOME/evolution-data-server/_build/scan-build/2026-08-11-054813-10-1 -x c /builds/GNOME/evolution-data-server/src/camel/providers/local/camel-maildir-store.c
1/*
2 * SPDX-FileCopyrightText: (C) 1999-2008 Novell, Inc. (www.novell.com)
3 * SPDX-License-Identifier: LGPL-2.0-or-later
4 * SPDX-FileContributor: Michael Zucchi <notzed@ximian.com>
5 */
6
7#include "evolution-data-server-config.h"
8
9#include <dirent.h>
10#include <errno(*__errno_location ()).h>
11#include <string.h>
12#include <unistd.h>
13#include <sys/stat.h>
14#include <sys/types.h>
15
16#include <glib/gstdio.h>
17#include <glib/gi18n-lib.h>
18
19#include "camel-maildir-folder.h"
20#include "camel-maildir-store.h"
21#include "camel-maildir-summary.h"
22
23#define d(x)
24
25/* after the space is a version of the folder structure */
26#define MAILDIR_CONTENT_VERSION_STR"maildir++ 1" "maildir++ 1"
27#define MAILDIR_CONTENT_VERSION1 1
28
29#define HIER_SEP"." "."
30#define HIER_SEP_CHAR'.' '.'
31
32#define CHECK_MKDIR(x,d)do { gint mkdir_ret = (x); if (mkdir_ret == -1 && (*__errno_location
()) != 17) { g_debug ("%s: mkdir of '%s' failed: %s", ((const
char*) (__func__)), (d), g_strerror ((*__errno_location ()))
); } } while (0)
G_STMT_STARTdo { \
33 gint mkdir_ret = (x); \
34 if (mkdir_ret == -1 && errno(*__errno_location ()) != EEXIST17) { \
35 g_debug ("%s: mkdir of '%s' failed: %s", G_STRFUNC((const char*) (__func__)), (d), g_strerror (errno(*__errno_location ()))); \
36 } \
37 } G_STMT_ENDwhile (0)
38
39struct _CamelMaildirStorePrivate {
40 gchar filename_flag_sep;
41 gboolean already_migrated;
42 gboolean can_escape_dots;
43};
44
45static CamelFolder * maildir_store_get_folder_sync (CamelStore *store, const gchar *folder_name, CamelStoreGetFolderFlags flags,
46 GCancellable *cancellable, GError **error);
47static CamelFolderInfo *maildir_store_create_folder_sync (CamelStore *store, const gchar *parent_name, const gchar *folder_name,
48 GCancellable *cancellable, GError **error);
49static gboolean maildir_store_delete_folder_sync (CamelStore * store, const gchar *folder_name, GCancellable *cancellable, GError **error);
50
51static gchar *maildir_full_name_to_dir_name (gboolean can_escape_dots, const gchar *full_name);
52static gchar *maildir_dir_name_to_fullname (gboolean can_escape_dots, const gchar *dir_name);
53static gchar *maildir_get_full_path (CamelLocalStore *ls, const gchar *full_name);
54static gchar *maildir_get_meta_path (CamelLocalStore *ls, const gchar *full_name, const gchar *ext);
55static void maildir_migrate_hierarchy (CamelMaildirStore *mstore, gint maildir_version, GCancellable *cancellable, GError **error);
56static gboolean maildir_version_requires_migrate (const gchar *meta_filename, gboolean *file_exists, gint *maildir_version);
57
58G_DEFINE_TYPE_WITH_PRIVATE (CamelMaildirStore, camel_maildir_store, CAMEL_TYPE_LOCAL_STORE)static void camel_maildir_store_init (CamelMaildirStore *self
); static void camel_maildir_store_class_init (CamelMaildirStoreClass
*klass); static GType camel_maildir_store_get_type_once (void
); static gpointer camel_maildir_store_parent_class = ((void*
)0); static gint CamelMaildirStore_private_offset; static void
camel_maildir_store_class_intern_init (gpointer klass) { camel_maildir_store_parent_class
= g_type_class_peek_parent (klass); if (CamelMaildirStore_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CamelMaildirStore_private_offset
); camel_maildir_store_class_init ((CamelMaildirStoreClass*) klass
); } __attribute__ ((__unused__)) static inline gpointer camel_maildir_store_get_instance_private
(CamelMaildirStore *self) { return (((gpointer) ((guint8*) (
self) + (glong) (CamelMaildirStore_private_offset)))); } GType
camel_maildir_store_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 = camel_maildir_store_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 camel_maildir_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_local_store_get_type ()), g_intern_static_string ("CamelMaildirStore"
), sizeof (CamelMaildirStoreClass), (GClassInitFunc)(void (*)
(void)) camel_maildir_store_class_intern_init, sizeof (CamelMaildirStore
), (GInstanceInitFunc)(void (*)(void)) camel_maildir_store_init
, (GTypeFlags) 0); { {{ CamelMaildirStore_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelMaildirStorePrivate)); };} }
return g_define_type_id; }
59
60/* This fixes up some historical cruft of names starting with "./" */
61static const gchar *
62md_canon_name (const gchar *a)
63{
64 if (a != NULL((void*)0)) {
65 if (a[0] == '/')
66 a++;
67 if (a[0] == '.' && a[1] == '/')
68 a+=2;
69 }
70
71 return a;
72}
73
74static CamelFolderInfo *
75maildir_store_create_folder_sync (CamelStore *store,
76 const gchar *parent_name,
77 const gchar *folder_name,
78 GCancellable *cancellable,
79 GError **error)
80{
81 CamelLocalSettings *local_settings;
82 CamelSettings *settings;
83 CamelService *service;
84 CamelFolder *folder;
85 CamelFolderInfo *info = NULL((void*)0);
86 gchar *name = NULL((void*)0), *fullname = NULL((void*)0);
87 gchar *path;
88 struct stat st;
89
90 /* This is a pretty hacky version of create folder, but should basically work */
91
92 service = CAMEL_SERVICE (store)((((CamelService*) (void *) ((store)))));
93
94 settings = camel_service_ref_settings (service);
95
96 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
97 path = camel_local_settings_dup_path (local_settings);
98
99 g_object_unref (settings);
100
101 if (!g_path_is_absolute (path)) {
102 g_set_error (
103 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
104 CAMEL_STORE_ERROR_NO_FOLDER,
105 _("Store root %s is not an absolute path")((char *) g_dgettext ("evolution-data-server", "Store root %s is not an absolute path"
))
, path);
106 goto exit;
107 }
108
109 if (folder_name && !CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots && strchr (folder_name, HIER_SEP_CHAR'.')) {
110 g_set_error (
111 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
112 CAMEL_STORE_ERROR_INVALID,
113 _("Cannot create folder containing “%s”")((char *) g_dgettext ("evolution-data-server", "Cannot create folder containing “%s”"
))
, HIER_SEP".");
114 goto exit;
115 }
116
117 if ((!parent_name || !*parent_name) && !g_ascii_strcasecmp (folder_name, "Inbox")) {
118 g_set_error (
119 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
120 CAMEL_STORE_ERROR_NO_FOLDER,
121 _("Folder %s already exists")((char *) g_dgettext ("evolution-data-server", "Folder %s already exists"
))
, folder_name);
122 goto exit;
123 }
124
125 if (parent_name && *parent_name) {
126 fullname = g_strdup_printf ("%s/%s", parent_name, folder_name);
127 name = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, fullname);
128 g_free (fullname);
129 } else
130 name = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, folder_name);
131
132 fullname = g_build_filename (path, name, NULL((void*)0));
133
134 g_free (name);
135 name = NULL((void*)0);
136
137 if (g_statstat (fullname, &st) == 0) {
138 g_set_error (
139 error, G_IO_ERRORg_io_error_quark(), G_IO_ERROR_EXISTS,
140 _("Folder %s already exists")((char *) g_dgettext ("evolution-data-server", "Folder %s already exists"
))
, folder_name);
141 goto exit;
142
143 } else if (errno(*__errno_location ()) != ENOENT2) {
144 g_set_error (
145 error, G_IO_ERRORg_io_error_quark(),
146 g_io_error_from_errno (errno(*__errno_location ())),
147 _("Cannot get folder: %s: %s")((char *) g_dgettext ("evolution-data-server", "Cannot get folder: %s: %s"
))
,
148 folder_name, g_strerror (errno(*__errno_location ())));
149 goto exit;
150 }
151
152 g_free (fullname);
153 fullname = NULL((void*)0);
154
155 if (parent_name && *parent_name)
156 name = g_strdup_printf ("%s/%s", parent_name, folder_name);
157 else
158 name = g_strdup_printf ("%s", folder_name);
159
160 if (camel_store_db_get_folder_id (camel_store_get_db (store), name) > 0) {
161 g_set_error (
162 error, G_IO_ERRORg_io_error_quark(), G_IO_ERROR_EXISTS,
163 _("Folder %s already exists")((char *) g_dgettext ("evolution-data-server", "Folder %s already exists"
))
, name);
164 goto exit;
165 }
166
167 folder = maildir_store_get_folder_sync (store, name, CAMEL_STORE_FOLDER_CREATE, cancellable, error);
168 if (folder) {
169 g_object_unref (folder);
170 info = CAMEL_STORE_GET_CLASS (store)((((CamelStoreClass*) (((GTypeInstance*) ((store)))->g_class
))))
->get_folder_info_sync (
171 store, name, 0, cancellable, error);
172 }
173
174exit:
175 g_free (fullname);
176 g_free (name);
177 g_free (path);
178
179 return info;
180}
181
182static CamelFolder *
183maildir_store_get_folder_sync (CamelStore *store,
184 const gchar *folder_name,
185 CamelStoreGetFolderFlags flags,
186 GCancellable *cancellable,
187 GError **error)
188{
189 CamelStoreClass *store_class;
190 CamelLocalSettings *local_settings;
191 CamelSettings *settings;
192 CamelService *service;
193 CamelMaildirStore *maildir_store;
194 gchar *name, *tmp, *cur, *new, *dir_name;
195 gchar *path;
196 struct stat st;
197 CamelFolder *folder = NULL((void*)0);
198
199 g_return_val_if_fail (CAMEL_IS_MAILDIR_STORE (store), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_24
= 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((store)); GType __t = ((camel_maildir_store_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_boolean_var_24 = 1; _g_boolean_var_24; }), 1))) { } else
{ g_return_if_fail_warning ("camel-local-provider", ((const char
*) (__func__)), "CAMEL_IS_MAILDIR_STORE (store)"); return (((
void*)0)); } } while (0)
;
200
201 maildir_store = CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))));
202
203 if (!maildir_store->priv->already_migrated &&
204 maildir_store->priv->can_escape_dots) {
205 CamelFolderInfo *folder_info;
206
207 /* Not interested in any errors here, this is to invoke folder
208 content migration only. */
209 folder_info = camel_store_get_folder_info_sync (store, NULL((void*)0), CAMEL_STORE_FOLDER_INFO_RECURSIVE, cancellable, NULL((void*)0));
210 if (folder_info)
211 camel_folder_info_free (folder_info);
212 }
213
214 service = CAMEL_SERVICE (store)((((CamelService*) (void *) ((store)))));
215
216 settings = camel_service_ref_settings (service);
217
218 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
219 path = camel_local_settings_dup_path (local_settings);
220
221 g_object_unref (settings);
222
223 folder_name = md_canon_name (folder_name);
224 dir_name = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, folder_name);
225
226 /* maildir++ directory names start with a '.' */
227 name = g_build_filename (path, dir_name, NULL((void*)0));
228
229 g_free (dir_name);
230 g_free (path);
231
232 /* Chain up to parent's get_folder() method. */
233 store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class)((((CamelStoreClass*) (void *) ((camel_maildir_store_parent_class
)))))
;
234 if (!store_class->get_folder_sync (store, name, flags, cancellable, error)) {
235 g_free (name);
236 return NULL((void*)0);
237 }
238
239 tmp = g_strdup_printf ("%s/tmp", name);
240 cur = g_strdup_printf ("%s/cur", name);
241 new = g_strdup_printf ("%s/new", name);
242
243 if (!g_ascii_strcasecmp (folder_name, "Inbox")) {
244 /* special case "." (aka inbox), may need to be created */
245 if (g_statstat (tmp, &st) != 0 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
246 || g_statstat (cur, &st) != 0 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
247 || g_statstat (new, &st) != 0 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) {
248 if ((g_mkdirmkdir (tmp, 0700) != 0 && errno(*__errno_location ()) != EEXIST17)
249 || (g_mkdirmkdir (cur, 0700) != 0 && errno(*__errno_location ()) != EEXIST17)
250 || (g_mkdirmkdir (new, 0700) != 0 && errno(*__errno_location ()) != EEXIST17)) {
251 g_set_error (
252 error, G_IO_ERRORg_io_error_quark(),
253 g_io_error_from_errno (errno(*__errno_location ())),
254 _("Cannot create folder “%s”: %s")((char *) g_dgettext ("evolution-data-server", "Cannot create folder “%s”: %s"
))
,
255 folder_name, g_strerror (errno(*__errno_location ())));
256 rmdir (tmp);
257 rmdir (cur);
258 rmdir (new);
259 goto fail;
260 }
261 }
262 folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error);
263 } else if (g_statstat (name, &st) == -1) {
264 /* folder doesn't exist, see if we should create it */
265 if (errno(*__errno_location ()) != ENOENT2) {
266 g_set_error (
267 error, G_IO_ERRORg_io_error_quark(),
268 g_io_error_from_errno (errno(*__errno_location ())),
269 _("Cannot get folder “%s”: %s")((char *) g_dgettext ("evolution-data-server", "Cannot get folder “%s”: %s"
))
,
270 folder_name, g_strerror (errno(*__errno_location ())));
271 } else if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) {
272 g_set_error (
273 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
274 CAMEL_STORE_ERROR_NO_FOLDER,
275 _("Cannot get folder “%s”: folder does not exist.")((char *) g_dgettext ("evolution-data-server", "Cannot get folder “%s”: folder does not exist."
))
,
276 folder_name);
277 } else {
278 if ((g_mkdirmkdir (name, 0700) != 0 && errno(*__errno_location ()) != EEXIST17)
279 || (g_mkdirmkdir (tmp, 0700) != 0 && errno(*__errno_location ()) != EEXIST17)
280 || (g_mkdirmkdir (cur, 0700) != 0 && errno(*__errno_location ()) != EEXIST17)
281 || (g_mkdirmkdir (new, 0700) != 0 && errno(*__errno_location ()) != EEXIST17)) {
282 g_set_error (
283 error, G_IO_ERRORg_io_error_quark(),
284 g_io_error_from_errno (errno(*__errno_location ())),
285 _("Cannot create folder “%s”: %s")((char *) g_dgettext ("evolution-data-server", "Cannot create folder “%s”: %s"
))
,
286 folder_name, g_strerror (errno(*__errno_location ())));
287 rmdir (tmp);
288 rmdir (cur);
289 rmdir (new);
290 rmdir (name);
291 } else {
292 folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error);
293 }
294 }
295 } else if (!S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
296 || g_statstat (tmp, &st) != 0 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
297 || g_statstat (cur, &st) != 0 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
298 || g_statstat (new, &st) != 0 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) {
299 /* folder exists, but not maildir */
300 g_set_error (
301 error, CAMEL_ERROR(camel_error_quark ()), CAMEL_ERROR_GENERIC,
302 _("Cannot get folder “%s”: not a maildir directory.")((char *) g_dgettext ("evolution-data-server", "Cannot get folder “%s”: not a maildir directory."
))
,
303 name);
304 } else {
305 folder = camel_maildir_folder_new (store, folder_name, flags, cancellable, error);
306 }
307fail:
308 g_free (name);
309 g_free (tmp);
310 g_free (cur);
311 g_free (new);
312
313 return folder;
314}
315
316static gboolean
317maildir_store_delete_folder_sync (CamelStore *store,
318 const gchar *folder_name,
319 GCancellable *cancellable,
320 GError **error)
321{
322 CamelLocalSettings *local_settings;
323 CamelSettings *settings;
324 CamelService *service;
325 gchar *name, *tmp, *cur, *new, *dir_name;
326 gchar *path;
327 struct stat st;
328 gboolean success = TRUE(!(0));
329
330 if (g_ascii_strcasecmp (folder_name, "Inbox") == 0) {
331 g_set_error (
332 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
333 CAMEL_STORE_ERROR_NO_FOLDER,
334 _("Cannot delete folder: %s: Invalid operation")((char *) g_dgettext ("evolution-data-server", "Cannot delete folder: %s: Invalid operation"
))
,
335 _("Inbox")((char *) g_dgettext ("evolution-data-server", "Inbox")));
336 return FALSE(0);
337 }
338
339 service = CAMEL_SERVICE (store)((((CamelService*) (void *) ((store)))));
340
341 settings = camel_service_ref_settings (service);
342
343 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
344 path = camel_local_settings_dup_path (local_settings);
345
346 g_object_unref (settings);
347
348 /* maildir++ directory names start with a '.' */
349 dir_name = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, folder_name);
350 name = g_build_filename (path, dir_name, NULL((void*)0));
351 g_free (dir_name);
352
353 g_free (path);
354
355 tmp = g_strdup_printf ("%s/tmp", name);
356 cur = g_strdup_printf ("%s/cur", name);
357 new = g_strdup_printf ("%s/new", name);
358
359 if (g_statstat (name, &st) == -1 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
360 || g_statstat (tmp, &st) == -1 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
361 || g_statstat (cur, &st) == -1 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
362 || g_statstat (new, &st) == -1 || !S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) {
363 g_set_error (
364 error, G_IO_ERRORg_io_error_quark(),
365 g_io_error_from_errno (errno(*__errno_location ())),
366 _("Could not delete folder “%s”: %s")((char *) g_dgettext ("evolution-data-server", "Could not delete folder “%s”: %s"
))
,
367 folder_name, errno(*__errno_location ()) ? g_strerror (errno(*__errno_location ())) :
368 _("not a maildir directory")((char *) g_dgettext ("evolution-data-server", "not a maildir directory"
))
);
369 } else {
370 gint err = 0;
371
372 /* remove subdirs first - will fail if not empty */
373 if (rmdir (cur) == -1 || rmdir (new) == -1) {
374 err = errno(*__errno_location ());
375 } else {
376 DIR *dir;
377 struct dirent *d;
378
379 /* for tmp (only), its contents is irrelevant */
380 dir = opendir (tmp);
381 if (dir) {
382 while ((d = readdir (dir))) {
383 gchar *dname = d->d_name, *file;
384
385 if (!strcmp (dname, ".") || !strcmp (dname, ".."))
386 continue;
387 file = g_strdup_printf ("%s/%s", tmp, dname);
388 unlink (file);
389 g_free (file);
390 }
391 closedir (dir);
392 }
393 if (rmdir (tmp) == -1 || rmdir (name) == -1)
394 err = errno(*__errno_location ());
395 }
396
397 if (err != 0) {
398 /* easier just to mkdir all (and let them fail), than remember what we got to */
399 CHECK_MKDIR (g_mkdir (name, 0700), name)do { gint mkdir_ret = (mkdir (name, 0700)); if (mkdir_ret == -
1 && (*__errno_location ()) != 17) { g_debug ("%s: mkdir of '%s' failed: %s"
, ((const char*) (__func__)), (name), g_strerror ((*__errno_location
()))); } } while (0)
;
400 CHECK_MKDIR (g_mkdir (cur, 0700), cur)do { gint mkdir_ret = (mkdir (cur, 0700)); if (mkdir_ret == -
1 && (*__errno_location ()) != 17) { g_debug ("%s: mkdir of '%s' failed: %s"
, ((const char*) (__func__)), (cur), g_strerror ((*__errno_location
()))); } } while (0)
;
401 CHECK_MKDIR (g_mkdir (new, 0700), new)do { gint mkdir_ret = (mkdir (new, 0700)); if (mkdir_ret == -
1 && (*__errno_location ()) != 17) { g_debug ("%s: mkdir of '%s' failed: %s"
, ((const char*) (__func__)), (new), g_strerror ((*__errno_location
()))); } } while (0)
;
402 CHECK_MKDIR (g_mkdir (tmp, 0700), tmp)do { gint mkdir_ret = (mkdir (tmp, 0700)); if (mkdir_ret == -
1 && (*__errno_location ()) != 17) { g_debug ("%s: mkdir of '%s' failed: %s"
, ((const char*) (__func__)), (tmp), g_strerror ((*__errno_location
()))); } } while (0)
;
403 g_set_error (
404 error, G_IO_ERRORg_io_error_quark(),
405 g_io_error_from_errno (err),
406 _("Could not delete folder “%s”: %s")((char *) g_dgettext ("evolution-data-server", "Could not delete folder “%s”: %s"
))
,
407 folder_name, g_strerror (err));
408 } else {
409 CamelStoreClass *store_class;
410
411 /* Chain up to parent's delete_folder() method. */
412 store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class)((((CamelStoreClass*) (void *) ((camel_maildir_store_parent_class
)))))
;
413 success = store_class->delete_folder_sync (
414 store, folder_name, cancellable, error);
415 }
416 }
417
418 g_free (name);
419 g_free (tmp);
420 g_free (cur);
421 g_free (new);
422
423 return success;
424}
425
426static void
427fill_fi (CamelStore *store,
428 CamelFolderInfo *fi,
429 guint32 flags,
430 GCancellable *cancellable)
431{
432 CamelFolder *folder;
433
434 folder = camel_object_bag_peek (camel_store_get_folders_bag (store), fi->full_name);
435 if (folder) {
436 CamelFolderSummary *summary;
437
438 if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0)
439 camel_folder_refresh_info_sync (folder, cancellable, NULL((void*)0));
440 summary = camel_folder_get_folder_summary (folder);
441 fi->unread = camel_folder_summary_get_unread_count (summary);
442 fi->total = camel_folder_summary_count (summary);
443 g_object_unref (folder);
444 } else {
445 CamelLocalSettings *local_settings;
446 CamelSettings *settings;
447 CamelService *service;
448 CamelMaildirStore *maildir_store;
449 gchar *folderpath, *dir_name;
450 CamelFolderSummary *s;
451 gchar *root;
452
453 service = CAMEL_SERVICE (store)((((CamelService*) (void *) ((store)))));
454
455 settings = camel_service_ref_settings (service);
456
457 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
458 root = camel_local_settings_dup_path (local_settings);
459
460 g_object_unref (settings);
461
462 maildir_store = CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))));
463
464 /* This should be fast enough not to have to test for INFO_FAST */
465 dir_name = maildir_full_name_to_dir_name (maildir_store->priv->can_escape_dots, fi->full_name);
466
467 if (!strcmp (dir_name, "."))
468 folderpath = g_strdup (root)g_strdup_inline (root);
469 else
470 folderpath = g_build_filename (root, dir_name, NULL((void*)0));
471
472 g_free (root);
473
474 s = (CamelFolderSummary *) camel_maildir_summary_new (NULL((void*)0), folderpath, NULL((void*)0), camel_maildir_store_get_filename_flag_sep (maildir_store));
475 if (camel_folder_summary_header_load (s, store, fi->full_name, NULL((void*)0))) {
476 fi->unread = camel_folder_summary_get_unread_count (s);
477 fi->total = camel_folder_summary_get_saved_count (s);
478 }
479 g_object_unref (s);
480 g_free (folderpath);
481 g_free (dir_name);
482 }
483
484 if (camel_local_store_is_main_store (CAMEL_LOCAL_STORE (store)((((CamelLocalStore*) (void *) ((store)))))) && fi->full_name
485 && (fi->flags & CAMEL_FOLDER_TYPE_MASK(0x3F << (10))) == CAMEL_FOLDER_TYPE_NORMAL)
486 fi->flags = (fi->flags & ~CAMEL_FOLDER_TYPE_MASK(0x3F << (10)))
487 | camel_local_store_get_folder_type_by_full_name (CAMEL_LOCAL_STORE (store)((((CamelLocalStore*) (void *) ((store))))), fi->full_name);
488}
489
490static CamelFolderInfo *
491scan_fi (CamelStore *store,
492 guint32 flags,
493 const gchar *full,
494 const gchar *name,
495 GCancellable *cancellable)
496{
497 CamelLocalSettings *local_settings;
498 CamelSettings *settings;
499 CamelService *service;
500 CamelFolderInfo *fi;
501 gchar *tmp, *cur, *new, *dir_name;
502 gchar *path;
503 struct stat st;
504
505 service = CAMEL_SERVICE (store)((((CamelService*) (void *) ((store)))));
506
507 settings = camel_service_ref_settings (service);
508
509 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
510 path = camel_local_settings_dup_path (local_settings);
511
512 g_object_unref (settings);
513
514 g_return_val_if_fail (path != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_25
= 0; if (path != ((void*)0)) _g_boolean_var_25 = 1; _g_boolean_var_25
; }), 1))) { } else { g_return_if_fail_warning ("camel-local-provider"
, ((const char*) (__func__)), "path != NULL"); return (((void
*)0)); } } while (0)
;
515
516 fi = camel_folder_info_new ();
517 fi->full_name = g_strdup (full)g_strdup_inline (full);
518 fi->display_name = g_strdup (name)g_strdup_inline (name);
519
520 fi->unread = -1;
521 fi->total = -1;
522
523 /* we only calculate nochildren properly if we're recursive */
524 if (((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) != 0))
525 fi->flags = CAMEL_FOLDER_NOCHILDREN;
526
527 dir_name = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, fi->full_name);
528 d (printf ("Adding maildir info: '%s' '%s' '%s'\n", fi->name, dir_name, fi->uri));
529
530 tmp = g_build_filename (path, dir_name, "tmp", NULL((void*)0));
531 cur = g_build_filename (path, dir_name, "cur", NULL((void*)0));
532 new = g_build_filename (path, dir_name, "new", NULL((void*)0));
533
534 if (!(g_statstat (cur, &st) == 0 && S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
535 && g_statstat (new, &st) == 0 && S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))
536 /* Create 'tmp' dir on demand, if other directories are there,
537 because some backup tools can drop the 'tmp' directory. */
538 && ((g_statstat (tmp, &st) == 0 && S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) || g_mkdirmkdir (tmp, 0700) == 0)))
539 fi->flags |= CAMEL_FOLDER_NOSELECT;
540
541 g_free (new);
542 g_free (cur);
543 g_free (tmp);
544 g_free (dir_name);
545
546 fill_fi (store, fi, flags, cancellable);
547
548 g_free (path);
549
550 return fi;
551}
552
553/* Folder names begin with a dot */
554static gchar *
555maildir_full_name_to_dir_name (gboolean can_escape_dots,
556 const gchar *full_name)
557{
558 gchar *path;
559
560 if (g_ascii_strcasecmp (full_name, "Inbox") == 0) {
561 path = g_strdup (".")g_strdup_inline (".");
562 } else {
563 if (g_ascii_strncasecmp (full_name, "Inbox/", 6) == 0)
564 path = g_strconcat ("/", full_name + 5, NULL((void*)0));
565 else
566 path = g_strconcat ("/", full_name, NULL((void*)0));
567
568 if (can_escape_dots && (strchr (path, HIER_SEP_CHAR'.') || strchr (path, '_'))) {
569 GString *tmp = g_string_new ("");
570 const gchar *pp;
571
572 for (pp = path; *pp; pp++) {
573 if (*pp == HIER_SEP_CHAR'.' || *pp == '_')
574 g_string_append_printf (tmp, "_%02X", *pp);
575 else
576 g_string_append_c (tmp, *pp)g_string_append_c_inline (tmp, *pp);
577 }
578
579 g_free (path);
580 path = g_string_free (tmp, FALSE(0));
581 }
582
583 g_strdelimit (path, "/", HIER_SEP_CHAR'.');
584 }
585
586 return path;
587}
588
589static gchar *
590maildir_dir_name_to_fullname (gboolean can_escape_dots,
591 const gchar *dir_name)
592{
593 gchar *full_name;
594
595 if (!g_ascii_strncasecmp (dir_name, "..", 2))
596 full_name = g_strconcat ("Inbox/", dir_name + 2, NULL((void*)0));
597 else
598 full_name = g_strdup (dir_name + 1)g_strdup_inline (dir_name + 1);
599
600 g_strdelimit (full_name, HIER_SEP".", '/');
601
602 if (can_escape_dots && strchr (full_name, '_')) {
603 gint ii, jj;
604
605 for (ii = 0, jj = 0; full_name[ii]; ii++, jj++) {
606 if (full_name[ii] == '_' && g_ascii_isxdigit (full_name[ii + 1])((g_ascii_table[(guchar) (full_name[ii + 1])] & G_ASCII_XDIGIT
) != 0)
&& g_ascii_isxdigit (full_name[ii + 2])((g_ascii_table[(guchar) (full_name[ii + 2])] & G_ASCII_XDIGIT
) != 0)
) {
607 full_name[jj] = 16 * g_ascii_xdigit_value (full_name[ii + 1]) + g_ascii_xdigit_value (full_name[ii + 2]);
608 ii += 2;
609 } else if (ii != jj) {
610 full_name[jj] = full_name[ii];
611 }
612 }
613
614 full_name[jj] = '\0';
615 }
616
617 return full_name;
618}
619
620static gint
621scan_dirs (CamelStore *store,
622 guint32 flags,
623 gboolean can_inbox_sibling,
624 CamelFolderInfo **topfi,
625 GCancellable *cancellable,
626 GError **error)
627{
628 CamelLocalSettings *local_settings;
629 CamelMaildirStore *maildir_store;
630 CamelSettings *settings;
631 CamelService *service;
632 CamelFolderInfo *fi;
633 GPtrArray *folders;
634 gint res = -1;
635 DIR *dir;
636 struct dirent *d;
637 gchar *path;
638
639 service = CAMEL_SERVICE (store)((((CamelService*) (void *) ((store)))));
640 maildir_store = CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))));
641
642 settings = camel_service_ref_settings (service);
643
644 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
645 path = camel_local_settings_dup_path (local_settings);
646
647 g_object_unref (settings);
648
649 g_return_val_if_fail (path != NULL, -1)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_26
= 0; if (path != ((void*)0)) _g_boolean_var_26 = 1; _g_boolean_var_26
; }), 1))) { } else { g_return_if_fail_warning ("camel-local-provider"
, ((const char*) (__func__)), "path != NULL"); return (-1); }
} while (0)
;
1
Assuming 'path' is not equal to null
2
Taking true branch
3
Taking true branch
4
Loop condition is false. Exiting loop
650
651 folders = g_ptr_array_new ();
652 if (!g_ascii_strcasecmp ((*topfi)->full_name, "Inbox"))
5
Assuming the condition is false
6
Taking false branch
653 g_ptr_array_add (folders, (*topfi));
654
655 dir = opendir (path);
656 if (dir
6.1
'dir' is not equal to NULL
== NULL((void*)0)) {
657 g_set_error (
658 error, G_IO_ERRORg_io_error_quark(),
659 g_io_error_from_errno (errno(*__errno_location ())),
660 _("Could not scan folder “%s”: %s")((char *) g_dgettext ("evolution-data-server", "Could not scan folder “%s”: %s"
))
,
661 path, g_strerror (errno(*__errno_location ())));
662 goto exit;
663 }
664
665 if (!maildir_store->priv->already_migrated &&
7
Assuming field 'already_migrated' is 0
9
Taking true branch
666 maildir_store->priv->can_escape_dots) {
8
Assuming field 'can_escape_dots' is not equal to 0
667 gchar *meta_path = NULL((void*)0), *ptr;
668 gint maildir_version = 0;
669 gboolean file_exists = FALSE(0), requires_migrate;
670
671 meta_path = maildir_get_meta_path ((CamelLocalStore *) store, "?", "maildir++");
672 ptr = strrchr (meta_path, '?');
673 if (!ptr) {
10
Assuming 'ptr' is non-null
11
Taking false branch
674 g_warn_if_reached ()do { g_warn_message ("camel-local-provider", "/builds/GNOME/evolution-data-server/src/camel/providers/local/camel-maildir-store.c"
, 674, ((const char*) (__func__)), ((void*)0)); } while (0)
;
675 closedir (dir);
676 res = -1;
677
678 goto exit;
679 }
680
681 maildir_store->priv->already_migrated = TRUE(!(0));
682
683 /* Do not migrate folders out of user's data data, which is completely
684 handled by Camel/Evolution, thus these tweaks can be done there. */
685 maildir_store->priv->can_escape_dots = g_str_has_prefix (meta_path, camel_service_get_user_data_dir (service))(__builtin_constant_p (camel_service_get_user_data_dir (service
))? __extension__ ({ const char * const __str = (meta_path); const
char * const __prefix = (camel_service_get_user_data_dir (service
)); gboolean __result = (0); if (__builtin_expect (__extension__
({ int _g_boolean_var_27 = 0; if (__str == ((void*)0) || __prefix
== ((void*)0)) _g_boolean_var_27 = 1; _g_boolean_var_27; }),
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) (meta_path, camel_service_get_user_data_dir
(service)) )
;
12
'?' condition is false
686
687 /* cannot pass dot inside maildir_get_meta_path(), because it escapes it */
688 ptr[0] = '.';
689
690 requires_migrate = maildir_version_requires_migrate (meta_path, &file_exists, &maildir_version);
13
Calling 'maildir_version_requires_migrate'
691 if (file_exists) {
692 /* Users can enable dot escaping by adding ..maildir++ file into the root Maildir folder */
693 maildir_store->priv->can_escape_dots = TRUE(!(0));
694 }
695
696 if (requires_migrate && maildir_store->priv->can_escape_dots)
697 maildir_migrate_hierarchy ((CamelMaildirStore *) store, maildir_version, cancellable, error);
698
699 g_free (meta_path);
700 }
701
702 while ((d = readdir (dir))) {
703 gchar *full_name, *filename;
704 const gchar *short_name;
705 struct stat st;
706
707 if (strcmp (d->d_name, "tmp") == 0
708 || strcmp (d->d_name, "cur") == 0
709 || strcmp (d->d_name, "new") == 0
710 || strcmp (d->d_name, ".#evolution") == 0
711 || strcmp (d->d_name, ".") == 0
712 || strcmp (d->d_name, "..") == 0
713 || !g_str_has_prefix (d->d_name, ".")(__builtin_constant_p (".")? __extension__ ({ const char * const
__str = (d->d_name); const char * const __prefix = (".");
gboolean __result = (0); if (__builtin_expect (__extension__
({ int _g_boolean_var_28 = 0; if (__str == ((void*)0) || __prefix
== ((void*)0)) _g_boolean_var_28 = 1; _g_boolean_var_28; }),
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) (d->d_name, ".") )
)
714
715 continue;
716
717 filename = g_build_filename (path, d->d_name, NULL((void*)0));
718 if (!(g_statstat (filename, &st) == 0 && S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000)))) {
719 g_free (filename);
720 continue;
721 }
722 g_free (filename);
723 full_name = maildir_dir_name_to_fullname (maildir_store->priv->can_escape_dots, d->d_name);
724 short_name = strrchr (full_name, '/');
725 if (!short_name)
726 short_name = full_name;
727 else
728 short_name++;
729
730 if ((g_ascii_strcasecmp ((*topfi)->full_name, "Inbox") != 0
731 && (!g_str_has_prefix (full_name, (*topfi)->full_name)(__builtin_constant_p ((*topfi)->full_name)? __extension__
({ const char * const __str = (full_name); const char * const
__prefix = ((*topfi)->full_name); gboolean __result = (0)
; if (__builtin_expect (__extension__ ({ int _g_boolean_var_29
= 0; if (__str == ((void*)0) || __prefix == ((void*)0)) _g_boolean_var_29
= 1; _g_boolean_var_29; }), 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) (full_name, (*topfi
)->full_name) )
||
732 (full_name[strlen ((*topfi)->full_name)] != '\0' &&
733 full_name[strlen ((*topfi)->full_name)] != '/')))
734 || (!can_inbox_sibling
735 && g_ascii_strcasecmp ((*topfi)->full_name, "Inbox") == 0
736 && (!g_str_has_prefix (full_name, (*topfi)->full_name)(__builtin_constant_p ((*topfi)->full_name)? __extension__
({ const char * const __str = (full_name); const char * const
__prefix = ((*topfi)->full_name); gboolean __result = (0)
; if (__builtin_expect (__extension__ ({ int _g_boolean_var_30
= 0; if (__str == ((void*)0) || __prefix == ((void*)0)) _g_boolean_var_30
= 1; _g_boolean_var_30; }), 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) (full_name, (*topfi
)->full_name) )
||
737 (full_name[strlen ((*topfi)->full_name)] != '\0' &&
738 full_name[strlen ((*topfi)->full_name)] != '/')))) {
739 g_free (full_name);
740 continue;
741 }
742
743 fi = scan_fi (store, flags, full_name, short_name, cancellable);
744 g_free (full_name);
745
746 g_ptr_array_add (folders, fi);
747 }
748
749 closedir (dir);
750
751 if (folders->len != 0) {
752 if (!g_ascii_strcasecmp ((*topfi)->full_name, "Inbox")) {
753 *topfi = camel_folder_info_build (folders, "", '/', TRUE(!(0)));
754 } else {
755 CamelFolderInfo *old_topfi = *topfi;
756
757 *topfi = camel_folder_info_build (folders, (*topfi)->full_name, '/', TRUE(!(0)));
758 camel_folder_info_free (old_topfi);
759 }
760
761 fi = *topfi;
762
763 if (fi && (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) != 0) {
764 while (fi) {
765 if (fi->child) {
766 fi->flags = fi->flags & (~CAMEL_FOLDER_NOCHILDREN);
767 fi->flags = fi->flags | CAMEL_FOLDER_CHILDREN;
768
769 fi = fi->child;
770 } else if (fi->next) {
771 fi = fi->next;
772 } else {
773 while (fi) {
774 fi = fi->parent;
775 if (fi && fi->next) {
776 fi = fi->next;
777 break;
778 }
779 }
780 }
781 }
782 }
783
784 res = 0;
785 } else
786 res = -1;
787
788exit:
789 g_ptr_array_free (folders, TRUE(!(0)));
790
791 g_free (path);
792
793 return res;
794}
795
796static guint
797maildir_store_hash_folder_name (gconstpointer a)
798{
799 return g_str_hash (md_canon_name (a));
800}
801
802static gboolean
803maildir_store_equal_folder_name (gconstpointer a,
804 gconstpointer b)
805{
806 return g_str_equal (md_canon_name (a), md_canon_name (b))(strcmp ((const char *) (md_canon_name (a)), (const char *) (
md_canon_name (b))) == 0)
;
807}
808
809static CamelFolderInfo *
810maildir_store_get_folder_info_sync (CamelStore *store,
811 const gchar *top,
812 CamelStoreGetFolderInfoFlags flags,
813 GCancellable *cancellable,
814 GError **error)
815{
816 CamelFolderInfo *fi = NULL((void*)0);
817
818 if (top == NULL((void*)0) || top[0] == 0) {
819 /* create a dummy "." parent inbox, use to scan, then put back at the top level */
820 fi = scan_fi (store, flags, "Inbox", _("Inbox")((char *) g_dgettext ("evolution-data-server", "Inbox")), cancellable);
821 if (scan_dirs (store, flags, TRUE(!(0)), &fi, cancellable, error) == -1)
822 goto fail;
823
824 fi->flags |= CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_TYPE_INBOX;
825 } else if (!strcmp (top, ".")) {
826 fi = scan_fi (store, flags, "Inbox", _("Inbox")((char *) g_dgettext ("evolution-data-server", "Inbox")), cancellable);
827 fi->flags |= CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_TYPE_INBOX;
828 } else {
829 const gchar *name = strrchr (top, '/');
830
831 fi = scan_fi (store, flags, top, name ? name + 1 : top, cancellable);
832 if (g_strcmp0 (fi->full_name, CAMEL_VTRASH_NAME".#evolution/Trash") != 0 &&
833 g_strcmp0 (fi->full_name, CAMEL_VJUNK_NAME".#evolution/Junk") != 0 &&
834 scan_dirs (store, flags, FALSE(0), &fi, cancellable, error) == -1)
835 goto fail;
836 }
837
838 return fi;
839
840fail:
841 camel_folder_info_free (fi);
842
843 return NULL((void*)0);
844}
845
846static CamelFolder *
847maildir_store_get_inbox_sync (CamelStore *store,
848 GCancellable *cancellable,
849 GError **error)
850{
851 return camel_store_get_folder_sync (
852 store, "Inbox", CAMEL_STORE_FOLDER_CREATE, cancellable, error);
853}
854
855static gboolean
856rename_traverse_fi (CamelStore *store,
857 CamelStoreClass *store_class,
858 CamelFolderInfo *fi,
859 const gchar *old_full_name_prefix,
860 const gchar *new_full_name_prefix,
861 GCancellable *cancellable,
862 GError **error)
863{
864 gint old_prefix_len = strlen (old_full_name_prefix);
865 gboolean ret = TRUE(!(0));
866
867 while (fi && ret) {
868 if (fi->full_name && g_str_has_prefix (fi->full_name, old_full_name_prefix)(__builtin_constant_p (old_full_name_prefix)? __extension__ (
{ const char * const __str = (fi->full_name); const char *
const __prefix = (old_full_name_prefix); gboolean __result =
(0); if (__builtin_expect (__extension__ ({ int _g_boolean_var_31
= 0; if (__str == ((void*)0) || __prefix == ((void*)0)) _g_boolean_var_31
= 1; _g_boolean_var_31; }), 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) (fi->full_name
, old_full_name_prefix) )
) {
869 gchar *new_full_name, *old_dir, *new_dir;
870
871 new_full_name = g_strconcat (new_full_name_prefix, fi->full_name + old_prefix_len, NULL((void*)0));
872 old_dir = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, fi->full_name);
873 new_dir = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, new_full_name);
874
875 /* Chain up to parent's rename_folder_sync() method. */
876 ret = store_class->rename_folder_sync (store, old_dir, new_dir, cancellable, error);
877
878 g_free (old_dir);
879 g_free (new_dir);
880 g_free (new_full_name);
881 }
882
883 if (fi->child && !rename_traverse_fi (store, store_class, fi->child, old_full_name_prefix, new_full_name_prefix, cancellable, error))
884 return FALSE(0);
885
886 fi = fi->next;
887 }
888
889 return ret;
890}
891
892static gboolean
893maildir_store_rename_folder_sync (CamelStore *store,
894 const gchar *old,
895 const gchar *new,
896 GCancellable *cancellable,
897 GError **error)
898{
899 CamelStoreClass *store_class;
900 gboolean ret;
901 gchar *old_dir, *new_dir;
902 CamelFolderInfo *subfolders;
903
904 if (strcmp (old, ".") == 0) {
905 g_set_error (
906 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
907 CAMEL_STORE_ERROR_NO_FOLDER,
908 _("Cannot rename folder: %s: Invalid operation")((char *) g_dgettext ("evolution-data-server", "Cannot rename folder: %s: Invalid operation"
))
,
909 _("Inbox")((char *) g_dgettext ("evolution-data-server", "Inbox")));
910 return FALSE(0);
911 }
912
913 if (!g_ascii_strcasecmp (new, "Inbox")) {
914 g_set_error (
915 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
916 CAMEL_STORE_ERROR_NO_FOLDER,
917 _("Folder %s already exists")((char *) g_dgettext ("evolution-data-server", "Folder %s already exists"
))
, new);
918 return FALSE(0);
919 }
920
921 if (new && !CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots && strchr (new, HIER_SEP_CHAR'.')) {
922 g_set_error (
923 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
924 CAMEL_STORE_ERROR_INVALID,
925 _("Cannot create folder containing “%s”")((char *) g_dgettext ("evolution-data-server", "Cannot create folder containing “%s”"
))
, HIER_SEP".");
926 return FALSE(0);
927 }
928
929 subfolders = maildir_store_get_folder_info_sync (
930 store, old,
931 CAMEL_STORE_FOLDER_INFO_RECURSIVE |
932 CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL,
933 cancellable, NULL((void*)0));
934
935 old_dir = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, old);
936 new_dir = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (store)((((CamelMaildirStore*) (void *) ((store)))))->priv->can_escape_dots, new);
937
938 /* Chain up to parent's rename_folder_sync() method. */
939 store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class)((((CamelStoreClass*) (void *) ((camel_maildir_store_parent_class
)))))
;
940 ret = store_class->rename_folder_sync (
941 store, old_dir, new_dir, cancellable, error);
942
943 if (subfolders) {
944 if (ret)
945 ret = rename_traverse_fi (
946 store, store_class,
947 subfolders->child,
948 old, new,
949 cancellable, error);
950
951 camel_folder_info_free (subfolders);
952 }
953
954 g_free (old_dir);
955 g_free (new_dir);
956
957 return ret;
958}
959
960static void
961camel_maildir_store_class_init (CamelMaildirStoreClass *class)
962{
963 CamelStoreClass *store_class;
964 CamelLocalStoreClass *local_class;
965
966 store_class = CAMEL_STORE_CLASS (class)((((CamelStoreClass*) (void *) ((class)))));
967 store_class->hash_folder_name = maildir_store_hash_folder_name;
968 store_class->equal_folder_name = maildir_store_equal_folder_name;
969 store_class->create_folder_sync = maildir_store_create_folder_sync;
970 store_class->get_folder_sync = maildir_store_get_folder_sync;
971 store_class->get_folder_info_sync = maildir_store_get_folder_info_sync;
972 store_class->get_inbox_folder_sync = maildir_store_get_inbox_sync;
973 store_class->delete_folder_sync = maildir_store_delete_folder_sync;
974 store_class->rename_folder_sync = maildir_store_rename_folder_sync;
975
976 local_class = CAMEL_LOCAL_STORE_CLASS (class)((((CamelLocalStoreClass*) (void *) ((class)))));
977 local_class->get_full_path = maildir_get_full_path;
978 local_class->get_meta_path = maildir_get_meta_path;
979}
980
981static void
982camel_maildir_store_init (CamelMaildirStore *maildir_store)
983{
984 maildir_store->priv = camel_maildir_store_get_instance_private (maildir_store);
985 maildir_store->priv->already_migrated = FALSE(0);
986 maildir_store->priv->can_escape_dots = TRUE(!(0));
987}
988
989static gchar *
990maildir_get_full_path (CamelLocalStore *ls,
991 const gchar *full_name)
992{
993 CamelLocalSettings *local_settings;
994 CamelSettings *settings;
995 CamelService *service;
996 gchar *filename;
997 gchar *dir_name;
998 gchar *path;
999
1000 service = CAMEL_SERVICE (ls)((((CamelService*) (void *) ((ls)))));
1001
1002 settings = camel_service_ref_settings (service);
1003
1004 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
1005 path = camel_local_settings_dup_path (local_settings);
1006
1007 g_object_unref (settings);
1008
1009 dir_name = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (ls)((((CamelMaildirStore*) (void *) ((ls)))))->priv->can_escape_dots, full_name);
1010 filename = g_build_filename (path, dir_name, NULL((void*)0));
1011 g_free (dir_name);
1012
1013 g_free (path);
1014
1015 return filename;
1016}
1017
1018static gchar *
1019maildir_get_meta_path (CamelLocalStore *ls,
1020 const gchar *full_name,
1021 const gchar *ext)
1022{
1023 CamelLocalSettings *local_settings;
1024 CamelSettings *settings;
1025 CamelService *service;
1026 gchar *filename;
1027 gchar *dir_name;
1028 gchar *path;
1029 gchar *tmp;
1030
1031 service = CAMEL_SERVICE (ls)((((CamelService*) (void *) ((ls)))));
1032
1033 settings = camel_service_ref_settings (service);
1034
1035 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
1036 path = camel_local_settings_dup_path (local_settings);
1037
1038 g_object_unref (settings);
1039
1040 dir_name = maildir_full_name_to_dir_name (CAMEL_MAILDIR_STORE (ls)((((CamelMaildirStore*) (void *) ((ls)))))->priv->can_escape_dots, full_name);
1041 tmp = g_build_filename (path, dir_name, NULL((void*)0));
1042 filename = g_strconcat (tmp, ext, NULL((void*)0));
1043 g_free (tmp);
1044 g_free (dir_name);
1045
1046 g_free (path);
1047
1048 return filename;
1049}
1050
1051/* Migration from old to maildir++ hierarchy */
1052
1053struct _scan_node {
1054 CamelFolderInfo *fi;
1055
1056 dev_t dnode;
1057 ino_t inode;
1058};
1059
1060static guint
1061scan_hash (gconstpointer d)
1062{
1063 const struct _scan_node *v = d;
1064
1065 return v->inode ^ v->dnode;
1066}
1067
1068static gboolean
1069scan_equal (gconstpointer a,
1070 gconstpointer b)
1071{
1072 const struct _scan_node *v1 = a, *v2 = b;
1073
1074 return v1->inode == v2->inode && v1->dnode == v2->dnode;
1075}
1076
1077static void
1078scan_free (gpointer k,
1079 gpointer v,
1080 gpointer d)
1081{
1082 g_free (k);
1083}
1084
1085static gint
1086scan_old_dir_info (CamelStore *store,
1087 CamelFolderInfo *topfi,
1088 GError **error)
1089{
1090 CamelLocalSettings *local_settings;
1091 CamelSettings *settings;
1092 CamelService *service;
1093 GQueue queue = G_QUEUE_INIT{ ((void*)0), ((void*)0), 0 };
1094 struct _scan_node *sn;
1095 gchar *path;
1096 gchar *tmp;
1097 GHashTable *visited;
1098 struct stat st;
1099 gint res = -1;
1100
1101 service = CAMEL_SERVICE (store)((((CamelService*) (void *) ((store)))));
1102
1103 settings = camel_service_ref_settings (service);
1104
1105 local_settings = CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings)))));
1106 path = camel_local_settings_dup_path (local_settings);
1107
1108 g_object_unref (settings);
1109
1110 visited = g_hash_table_new (scan_hash, scan_equal);
1111
1112 sn = g_malloc0 (sizeof (*sn));
1113 sn->fi = topfi;
1114 g_queue_push_tail (&queue, sn);
1115 g_hash_table_insert (visited, sn, sn);
1116
1117 while (!g_queue_is_empty (&queue)) {
1118 gchar *name;
1119 DIR *dir;
1120 struct dirent *d;
1121 CamelFolderInfo *last;
1122
1123 sn = g_queue_pop_head (&queue);
1124
1125 last = (CamelFolderInfo *) &sn->fi->child;
1126
1127 if (!strcmp (sn->fi->full_name, "."))
1128 name = g_strdup (path)g_strdup_inline (path);
1129 else
1130 name = g_build_filename (path, sn->fi->full_name, NULL((void*)0));
1131
1132 dir = opendir (name);
1133 if (dir == NULL((void*)0)) {
1134 g_free (name);
1135 g_set_error (
1136 error, G_IO_ERRORg_io_error_quark(),
1137 g_io_error_from_errno (errno(*__errno_location ())),
1138 _("Could not scan folder “%s”: %s")((char *) g_dgettext ("evolution-data-server", "Could not scan folder “%s”: %s"
))
,
1139 path, g_strerror (errno(*__errno_location ())));
1140 goto exit;
1141 }
1142
1143 while ((d = readdir (dir))) {
1144 if (strcmp (d->d_name, "tmp") == 0
1145 || strcmp (d->d_name, "cur") == 0
1146 || strcmp (d->d_name, "new") == 0
1147 || strcmp (d->d_name, ".#evolution") == 0
1148 || strcmp (d->d_name, ".") == 0
1149 || strcmp (d->d_name, "..") == 0)
1150 continue;
1151
1152 tmp = g_build_filename (name, d->d_name, NULL((void*)0));
1153 if (stat (tmp, &st) == 0 && S_ISDIR (st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) {
1154 struct _scan_node in;
1155
1156 memset (&in, 0, sizeof (struct _scan_node));
1157 in.dnode = st.st_dev;
1158 in.inode = st.st_ino;
1159
1160 /* see if we've visited already */
1161 if (g_hash_table_lookup (visited, &in) == NULL((void*)0)) {
1162 struct _scan_node *snew = g_malloc (sizeof (*snew));
1163 gchar *full;
1164 CamelFolderInfo *fi = NULL((void*)0);
1165
1166 snew->dnode = in.dnode;
1167 snew->inode = in.inode;
1168
1169 if (!strcmp (sn->fi->full_name, "."))
1170 full = g_strdup (d->d_name)g_strdup_inline (d->d_name);
1171 else
1172 full = g_strdup_printf ("%s/%s", sn->fi->full_name, d->d_name);
1173
1174 fi = camel_folder_info_new ();
1175 fi->full_name = full;
1176 fi->display_name = g_strdup (d->d_name)g_strdup_inline (d->d_name);
1177 snew->fi = fi;
1178
1179 last->next = snew->fi;
1180 last = snew->fi;
1181 snew->fi->parent = sn->fi;
1182
1183 g_hash_table_insert (visited, snew, snew);
1184 g_queue_push_tail (&queue, snew);
1185 }
1186 }
1187 g_free (tmp);
1188 }
1189 closedir (dir);
1190 g_free (name);
1191 }
1192
1193 res = 0;
1194
1195exit:
1196 g_hash_table_foreach (visited, scan_free, NULL((void*)0));
1197 g_hash_table_destroy (visited);
1198
1199 g_free (path);
1200
1201 return res;
1202}
1203
1204static void
1205maildir_maybe_rename_old_folder (CamelMaildirStore *mstore,
1206 CamelFolderInfo *fi,
1207 gint maildir_version,
1208 GCancellable *cancellable,
1209 GError **error)
1210{
1211 gchar *new_name = NULL((void*)0);
1212
1213 if (g_str_equal (fi->full_name, ".")(strcmp ((const char *) (fi->full_name), (const char *) ("."
)) == 0)
|| g_str_equal (fi->full_name, "..")(strcmp ((const char *) (fi->full_name), (const char *) (".."
)) == 0)
)
1214 return;
1215
1216 if (maildir_version == -1) {
1217 /* this is when maildir was not converted yet to maildir++ at all,
1218 * the '_' and '.' are still there and the dir separator is slash
1219 */
1220 new_name = maildir_full_name_to_dir_name (mstore->priv->can_escape_dots, fi->full_name);
1221 } else if (maildir_version == 0) {
1222 /* this is a conversion with maildir folder being already there,
1223 * only with no version; there should be escaped only '_', because
1224 * the '.' is already garbled;
1225 * fi->full_name is a dir name here
1226 */
1227 gchar *full_name;
1228
1229 if (!g_ascii_strncasecmp (fi->full_name, "..", 2))
1230 full_name = g_strconcat ("Inbox/", fi->full_name + 2, NULL((void*)0));
1231 else if (fi->full_name[0] == '.')
1232 full_name = g_strdup (fi->full_name + 1)g_strdup_inline (fi->full_name + 1);
1233 else
1234 full_name = g_strdup (fi->full_name)g_strdup_inline (fi->full_name);
1235
1236 g_strdelimit (full_name, HIER_SEP".", '/');
1237
1238 new_name = maildir_full_name_to_dir_name (mstore->priv->can_escape_dots, full_name);
1239
1240 g_free (full_name);
1241 } else {
1242 return;
1243 }
1244
1245 if (!g_str_equal (fi->full_name, new_name)(strcmp ((const char *) (fi->full_name), (const char *) (new_name
)) == 0)
) {
1246 CamelStoreClass *store_class;
1247 GError *local_error = NULL((void*)0);
1248
1249 store_class = CAMEL_STORE_CLASS (camel_maildir_store_parent_class)((((CamelStoreClass*) (void *) ((camel_maildir_store_parent_class
)))))
;
1250 /* Do not propagate these errors, only warn about them on console */
1251 store_class->rename_folder_sync ((CamelStore *) mstore, fi->full_name, new_name, cancellable, &local_error);
1252
1253 if (local_error) {
1254 g_warning ("%s: Failed to rename '%s' to '%s': %s", G_STRFUNC((const char*) (__func__)), fi->full_name, new_name, local_error->message);
1255 g_error_free (local_error);
1256 }
1257 }
1258
1259 g_free (new_name);
1260}
1261
1262static void
1263traverse_rename_folder_info (CamelMaildirStore *mstore,
1264 CamelFolderInfo *fi,
1265 gint maildir_version,
1266 GCancellable *cancellable,
1267 GError **error)
1268{
1269 while (fi != NULL((void*)0)) {
1270 if (fi->child)
1271 traverse_rename_folder_info (mstore, fi->child, maildir_version, cancellable, error);
1272
1273 maildir_maybe_rename_old_folder (mstore, fi, maildir_version, cancellable, error);
1274
1275 fi = fi->next;
1276 }
1277}
1278
1279static gboolean
1280maildir_version_requires_migrate (const gchar *meta_filename,
1281 gboolean *file_exists,
1282 gint *maildir_version)
1283{
1284 FILE *metafile;
1285 gint cc;
1286 gint verpos = 0;
1287 gboolean res = FALSE(0);
1288
1289 g_return_val_if_fail (meta_filename != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_32
= 0; if (meta_filename != ((void*)0)) _g_boolean_var_32 = 1;
_g_boolean_var_32; }), 1))) { } else { g_return_if_fail_warning
("camel-local-provider", ((const char*) (__func__)), "meta_filename != NULL"
); return ((0)); } } while (0)
;
14
Taking true branch
15
Taking true branch
16
Loop condition is false. Exiting loop
1290 g_return_val_if_fail (file_exists != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_33
= 0; if (file_exists != ((void*)0)) _g_boolean_var_33 = 1; _g_boolean_var_33
; }), 1))) { } else { g_return_if_fail_warning ("camel-local-provider"
, ((const char*) (__func__)), "file_exists != NULL"); return (
(0)); } } while (0)
;
17
Taking true branch
18
Taking true branch
19
Loop condition is false. Exiting loop
1291 g_return_val_if_fail (maildir_version != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_34
= 0; if (maildir_version != ((void*)0)) _g_boolean_var_34 = 1
; _g_boolean_var_34; }), 1))) { } else { g_return_if_fail_warning
("camel-local-provider", ((const char*) (__func__)), "maildir_version != NULL"
); return ((0)); } } while (0)
;
20
Taking true branch
21
Taking true branch
22
Loop condition is false. Exiting loop
1292
1293 /* nonexistent file is -1 */
1294 *maildir_version = -1;
1295 *file_exists = FALSE(0);
1296
1297 if (!g_file_test (meta_filename, G_FILE_TEST_EXISTS))
23
Assuming the condition is false
24
Taking false branch
1298 return TRUE(!(0));
1299
1300 /* existing file without version is 0 */
1301 *maildir_version = 0;
1302 *file_exists = TRUE(!(0));
1303
1304 metafile = fopen (meta_filename, "rb");
1305 if (!metafile
24.1
'metafile' is non-null
)
25
Taking false branch
1306 return FALSE(0);
1307
1308 while (cc = fgetc (metafile), !res
26.1
'res' is 0
&& !feof (metafile)) {
26
Assuming this stream operation fails
28
File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior
1309 if (verpos
26.2
'verpos' is <= 1
> 1 && MAILDIR_CONTENT_VERSION_STR"maildir++ 1"[verpos - 1] == ' ') {
1310 if (cc >= '0' && cc <= '9') {
1311 (*maildir_version) = (*maildir_version) * 10 + cc - '0';
1312 } else if (cc == ' ' || cc == '\n' || cc == '\r' || cc == '\t') {
1313 break;
1314 } else {
1315 res = TRUE(!(0));
1316 }
1317 } else if (cc == MAILDIR_CONTENT_VERSION_STR"maildir++ 1"[verpos]) {
27
Taking false branch
1318 verpos++;
1319 } else {
1320 res = TRUE(!(0));
1321 }
1322 }
1323
1324 fclose (metafile);
1325
1326 return res || (*maildir_version) < MAILDIR_CONTENT_VERSION1;
1327}
1328
1329static void
1330maildir_migrate_hierarchy (CamelMaildirStore *mstore,
1331 gint maildir_version,
1332 GCancellable *cancellable,
1333 GError **error)
1334{
1335 CamelFolderInfo *topfi;
1336 gchar *meta_path = NULL((void*)0), *ptr;
1337
1338 g_return_if_fail (mstore->priv->can_escape_dots)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_35
= 0; if (mstore->priv->can_escape_dots) _g_boolean_var_35
= 1; _g_boolean_var_35; }), 1))) { } else { g_return_if_fail_warning
("camel-local-provider", ((const char*) (__func__)), "mstore->priv->can_escape_dots"
); return; } } while (0)
;
1339
1340 topfi = camel_folder_info_new ();
1341 topfi->full_name = g_strdup (".")g_strdup_inline (".");
1342 topfi->display_name = g_strdup ("Inbox")g_strdup_inline ("Inbox");
1343
1344 if (scan_old_dir_info ((CamelStore *) mstore, topfi, error) == -1) {
1345 g_warning ("%s: Failed to scan the old folder info", G_STRFUNC((const char*) (__func__)));
1346 goto done;
1347 }
1348
1349 meta_path = maildir_get_meta_path ((CamelLocalStore *) mstore, "?", "maildir++");
1350 ptr = strrchr (meta_path, '?');
1351 g_return_if_fail (ptr != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_36
= 0; if (ptr != ((void*)0)) _g_boolean_var_36 = 1; _g_boolean_var_36
; }), 1))) { } else { g_return_if_fail_warning ("camel-local-provider"
, ((const char*) (__func__)), "ptr != NULL"); return; } } while
(0)
;
1352
1353 /* cannot pass dot inside maildir_get_meta_path(), because it is escaped */
1354 ptr[0] = '.';
1355
1356 /* First create/overwrite the file, only then do the migration, otherwise,
1357 if the file creation fails, the folder structure would be migrated repeatedly. */
1358 if (!g_file_set_contents (meta_path, MAILDIR_CONTENT_VERSION_STR"maildir++ 1", -1, error) || (error && *error)) {
1359 g_warning ("Failed to save the maildir version in ‘%s’.", meta_path);
1360 goto done;
1361 }
1362
1363 if (maildir_version < 1) {
1364 traverse_rename_folder_info (mstore, topfi, maildir_version, cancellable, error);
1365 }
1366
1367done:
1368 camel_folder_info_free (topfi);
1369 g_free (meta_path);
1370}
1371
1372gchar
1373camel_maildir_store_get_filename_flag_sep (CamelMaildirStore *maildir_store)
1374{
1375 g_return_val_if_fail (CAMEL_IS_MAILDIR_STORE (maildir_store), CAMEL_MAILDIR_FILENAME_FLAG_SEP)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_37
= 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((maildir_store)); GType __t = ((camel_maildir_store_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_boolean_var_37 = 1; _g_boolean_var_37; }), 1)
)) { } else { g_return_if_fail_warning ("camel-local-provider"
, ((const char*) (__func__)), "CAMEL_IS_MAILDIR_STORE (maildir_store)"
); return (':'); } } while (0)
;
1376
1377 /* Populate the value on the first access. It's too early in the constructed(),
1378 the settings might not be read there yet. */
1379 if (!maildir_store->priv->filename_flag_sep) {
1380 CamelSettings *settings;
1381
1382 settings = camel_service_ref_settings (CAMEL_SERVICE (maildir_store)((((CamelService*) (void *) ((maildir_store))))));
1383
1384 if (camel_local_settings_get_maildir_alt_flag_sep (CAMEL_LOCAL_SETTINGS (settings)((((CamelLocalSettings*) (void *) ((settings))))))) {
1385 maildir_store->priv->filename_flag_sep = CAMEL_MAILDIR_FILENAME_FLAG_SEP_ALT'!';
1386 } else {
1387 maildir_store->priv->filename_flag_sep = CAMEL_MAILDIR_FILENAME_FLAG_SEP':';
1388 }
1389
1390 g_clear_object (&settings)do { _Static_assert (sizeof *((&settings)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&settings
))) _pp = ((&settings)); __typeof__ (*((&settings))) _ptr
= *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr)
; } while (0)
;
1391 }
1392
1393 return maildir_store->priv->filename_flag_sep;
1394}