1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
4  *
5  * This library is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "evolution-data-server-config.h"
19 
20 #include <stdio.h>
21 
22 #include "camel/camel.h"
23 #include "camel-maildir-summary.h"
24 
25 #include "camel-maildir-message-info.h"
26 
27 struct _CamelMaildirMessageInfoPrivate {
28 	gchar *filename;
29 };
30 
31 enum {
32 	PROP_0,
33 	PROP_FILENAME
34 };
35 
G_DEFINE_TYPE_WITH_PRIVATE(CamelMaildirMessageInfo,camel_maildir_message_info,CAMEL_TYPE_MESSAGE_INFO_BASE)36 G_DEFINE_TYPE_WITH_PRIVATE (CamelMaildirMessageInfo, camel_maildir_message_info, CAMEL_TYPE_MESSAGE_INFO_BASE)
37 
38 static CamelMessageInfo *
39 maildir_message_info_clone (const CamelMessageInfo *mi,
40 			    CamelFolderSummary *assign_summary)
41 {
42 	CamelMessageInfo *result;
43 
44 	g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mi), NULL);
45 
46 	result = CAMEL_MESSAGE_INFO_CLASS (camel_maildir_message_info_parent_class)->clone (mi, assign_summary);
47 	if (!result)
48 		return NULL;
49 
50 	if (CAMEL_IS_MAILDIR_MESSAGE_INFO (result)) {
51 		CamelMaildirMessageInfo *mmi, *mmi_result;
52 
53 		mmi = CAMEL_MAILDIR_MESSAGE_INFO (mi);
54 		mmi_result = CAMEL_MAILDIR_MESSAGE_INFO (result);
55 
56 		/* safe-guard that the mmi's filename doesn't change before it's copied to mmi_result */
57 		camel_message_info_property_lock (mi);
58 
59 		camel_maildir_message_info_set_filename (mmi_result, camel_maildir_message_info_get_filename (mmi));
60 
61 		camel_message_info_property_unlock (mi);
62 	}
63 
64 	return result;
65 }
66 
67 static gboolean
maildir_message_info_load(CamelMessageInfo * mi,const CamelMIRecord * record,gchar ** bdata_ptr)68 maildir_message_info_load (CamelMessageInfo *mi,
69 			   const CamelMIRecord *record,
70 			   /* const */ gchar **bdata_ptr)
71 {
72 	CamelMaildirMessageInfo *mmi;
73 
74 	g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mi), FALSE);
75 	g_return_val_if_fail (record != NULL, FALSE);
76 	g_return_val_if_fail (bdata_ptr != NULL, FALSE);
77 
78 	if (!CAMEL_MESSAGE_INFO_CLASS (camel_maildir_message_info_parent_class)->load ||
79 	    !CAMEL_MESSAGE_INFO_CLASS (camel_maildir_message_info_parent_class)->load (mi, record, bdata_ptr))
80 		return FALSE;
81 
82 	mmi = CAMEL_MAILDIR_MESSAGE_INFO (mi);
83 
84 	camel_maildir_message_info_take_filename (mmi, camel_maildir_summary_info_to_name (mi));
85 
86 	return TRUE;
87 }
88 
89 static void
maildir_message_info_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)90 maildir_message_info_set_property (GObject *object,
91 				   guint property_id,
92 				   const GValue *value,
93 				   GParamSpec *pspec)
94 {
95 	CamelMaildirMessageInfo *mmi = CAMEL_MAILDIR_MESSAGE_INFO (object);
96 
97 	switch (property_id) {
98 	case PROP_FILENAME:
99 		camel_maildir_message_info_set_filename (mmi, g_value_get_string (value));
100 		return;
101 	}
102 
103 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
104 }
105 
106 static void
maildir_message_info_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)107 maildir_message_info_get_property (GObject *object,
108 				   guint property_id,
109 				   GValue *value,
110 				   GParamSpec *pspec)
111 {
112 	CamelMaildirMessageInfo *mmi = CAMEL_MAILDIR_MESSAGE_INFO (object);
113 
114 	switch (property_id) {
115 	case PROP_FILENAME:
116 		g_value_set_string (value, camel_maildir_message_info_get_filename (mmi));
117 		return;
118 	}
119 
120 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
121 }
122 
123 static void
maildir_message_info_dispose(GObject * object)124 maildir_message_info_dispose (GObject *object)
125 {
126 	CamelMaildirMessageInfo *mmi = CAMEL_MAILDIR_MESSAGE_INFO (object);
127 
128 	g_free (mmi->priv->filename);
129 	mmi->priv->filename = NULL;
130 
131 	/* Chain up to parent's method. */
132 	G_OBJECT_CLASS (camel_maildir_message_info_parent_class)->dispose (object);
133 }
134 
135 static void
camel_maildir_message_info_class_init(CamelMaildirMessageInfoClass * class)136 camel_maildir_message_info_class_init (CamelMaildirMessageInfoClass *class)
137 {
138 	CamelMessageInfoClass *mi_class;
139 	GObjectClass *object_class;
140 
141 	mi_class = CAMEL_MESSAGE_INFO_CLASS (class);
142 	mi_class->clone = maildir_message_info_clone;
143 	mi_class->load = maildir_message_info_load;
144 
145 	object_class = G_OBJECT_CLASS (class);
146 	object_class->set_property = maildir_message_info_set_property;
147 	object_class->get_property = maildir_message_info_get_property;
148 	object_class->dispose = maildir_message_info_dispose;
149 
150 	/**
151 	 * CamelMaildirMessageInfo:filename
152 	 *
153 	 * File name of the message on the disk.
154 	 *
155 	 * Since: 3.24
156 	 **/
157 	g_object_class_install_property (
158 		object_class,
159 		PROP_FILENAME,
160 		g_param_spec_string (
161 			"filename",
162 			"Filename",
163 			NULL,
164 			NULL,
165 			G_PARAM_READWRITE |
166 			G_PARAM_EXPLICIT_NOTIFY |
167 			G_PARAM_STATIC_STRINGS));
168 }
169 
170 static void
camel_maildir_message_info_init(CamelMaildirMessageInfo * mmi)171 camel_maildir_message_info_init (CamelMaildirMessageInfo *mmi)
172 {
173 	mmi->priv = camel_maildir_message_info_get_instance_private (mmi);
174 }
175 
176 const gchar *
camel_maildir_message_info_get_filename(const CamelMaildirMessageInfo * mmi)177 camel_maildir_message_info_get_filename (const CamelMaildirMessageInfo *mmi)
178 {
179 	CamelMessageInfo *mi;
180 	const gchar *result;
181 
182 	g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mmi), NULL);
183 
184 	mi = CAMEL_MESSAGE_INFO (mmi);
185 
186 	camel_message_info_property_lock (mi);
187 	result = mmi->priv->filename;
188 	camel_message_info_property_unlock (mi);
189 
190 	return result;
191 }
192 
193 gchar *
camel_maildir_message_info_dup_filename(const CamelMaildirMessageInfo * mmi)194 camel_maildir_message_info_dup_filename (const CamelMaildirMessageInfo *mmi)
195 {
196 	CamelMessageInfo *mi;
197 	gchar *result;
198 
199 	g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mmi), NULL);
200 
201 	mi = CAMEL_MESSAGE_INFO (mmi);
202 
203 	camel_message_info_property_lock (mi);
204 	result = g_strdup (mmi->priv->filename);
205 	camel_message_info_property_unlock (mi);
206 
207 	return result;
208 }
209 
210 gboolean
camel_maildir_message_info_set_filename(CamelMaildirMessageInfo * mmi,const gchar * filename)211 camel_maildir_message_info_set_filename (CamelMaildirMessageInfo *mmi,
212 					 const gchar *filename)
213 {
214 	g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mmi), FALSE);
215 
216 	return camel_maildir_message_info_take_filename (mmi, g_strdup (filename));
217 }
218 
219 gboolean
camel_maildir_message_info_take_filename(CamelMaildirMessageInfo * mmi,gchar * filename)220 camel_maildir_message_info_take_filename (CamelMaildirMessageInfo *mmi,
221 					  gchar *filename)
222 {
223 	CamelMessageInfo *mi;
224 	gboolean changed;
225 
226 	g_return_val_if_fail (CAMEL_IS_MAILDIR_MESSAGE_INFO (mmi), FALSE);
227 
228 	mi = CAMEL_MESSAGE_INFO (mmi);
229 
230 	camel_message_info_property_lock (mi);
231 
232 	changed = g_strcmp0 (mmi->priv->filename, filename) != 0;
233 
234 	if (changed) {
235 		g_free (mmi->priv->filename);
236 		mmi->priv->filename = filename;
237 	} else if (filename != mmi->priv->filename) {
238 		g_free (filename);
239 	}
240 
241 	camel_message_info_property_unlock (mi);
242 
243 	if (changed && !camel_message_info_get_abort_notifications (mi)) {
244 		g_object_notify (G_OBJECT (mmi), "filename");
245 		camel_message_info_set_dirty (mi, TRUE);
246 	}
247 
248 	return changed;
249 }
250