2 * Claws Mail templates subsystem
3 * Copyright (C) 2001 Alexander Barinov
4 * Copyright (C) 2001-2021 The Claws Mail team
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include <glib/gi18n.h>
33 #include "file-utils.h"
35 static GSList
*template_list
;
37 static Template
*template_load(gchar
*filename
)
44 if ((fp
= claws_fopen(filename
, "rb")) == NULL
) {
45 FILE_OP_ERROR(filename
, "claws_fopen");
49 tmpl
= g_new(Template
, 1);
50 tmpl
->load_filename
= g_strdup(filename
);
60 while (claws_fgets(buf
, sizeof(buf
), fp
) != NULL
) {
63 else if (!g_ascii_strncasecmp(buf
, "Name:", 5))
64 tmpl
->name
= g_strdup(g_strstrip(buf
+ 5));
65 else if (!g_ascii_strncasecmp(buf
, "From:", 5))
66 tmpl
->from
= g_strdup(g_strstrip(buf
+ 5));
67 else if (!g_ascii_strncasecmp(buf
, "To:", 3))
68 tmpl
->to
= g_strdup(g_strstrip(buf
+ 3));
69 else if (!g_ascii_strncasecmp(buf
, "Cc:", 3))
70 tmpl
->cc
= g_strdup(g_strstrip(buf
+ 3));
71 else if (!g_ascii_strncasecmp(buf
, "Bcc:", 4))
72 tmpl
->bcc
= g_strdup(g_strstrip(buf
+ 4));
73 else if (!g_ascii_strncasecmp(buf
, "Reply-To:", 9))
74 tmpl
->replyto
= g_strdup(g_strstrip(buf
+ 9));
75 else if (!g_ascii_strncasecmp(buf
, "Subject:", 8))
76 tmpl
->subject
= g_strdup(g_strstrip(buf
+ 8));
80 g_warning("wrong template format");
86 if ((bytes_read
= claws_fread(buf
, 1, sizeof(buf
), fp
)) == 0) {
87 if (claws_ferror(fp
)) {
88 FILE_OP_ERROR(filename
, "claws_fread");
95 tmpl
->value
= g_strndup(buf
, bytes_read
);
100 void template_free(Template
*tmpl
)
102 g_free(tmpl
->load_filename
);
104 g_free(tmpl
->subject
);
109 g_free(tmpl
->replyto
);
114 static void template_clear_config(GSList
*tmpl_list
)
119 for (cur
= tmpl_list
; cur
!= NULL
; cur
= cur
->next
) {
120 tmpl
= (Template
*)cur
->data
;
123 g_slist_free(tmpl_list
);
126 static gint
tmpl_compare(gconstpointer tmpl1
, gconstpointer tmpl2
)
128 gchar
*basename1
, *basename2
;
129 long filenum1
, filenum2
;
132 if ((Template
*)tmpl1
== NULL
|| (Template
*)tmpl2
== NULL
)
135 if (((Template
*)tmpl1
)->load_filename
== NULL
|| ((Template
*)tmpl2
)->load_filename
== NULL
)
138 basename1
= g_path_get_basename(((Template
*)tmpl1
)->load_filename
);
139 basename2
= g_path_get_basename(((Template
*)tmpl2
)->load_filename
);
140 filenum1
= atol(basename1
);
141 filenum2
= atol(basename2
);
145 if (filenum1
== 0 || filenum2
== 0)
148 if (filenum1
< filenum2
)
151 if (filenum1
> filenum2
)
157 GSList
*template_read_config(void)
161 const gchar
*dir_name
;
162 GSList
*tmpl_list
= NULL
;
164 path
= get_template_dir();
165 debug_print("%s:%d reading templates dir %s\n",
166 __FILE__
, __LINE__
, path
);
168 if (!is_dir_exist(path
)) {
169 if (make_dir(path
) < 0)
173 if ((dir
= g_dir_open(path
, 0, NULL
)) == NULL
) {
174 g_warning("failed to open directory: '%s'", path
);
178 while ((dir_name
= g_dir_read_name(dir
)) != NULL
) {
181 gchar
*filename
= g_strconcat(path
, G_DIR_SEPARATOR_S
,
184 if (g_stat(filename
, &s
) != 0 || !S_ISREG(s
.st_mode
) ) {
185 debug_print("%s:%d %s is not an ordinary file\n",
186 __FILE__
, __LINE__
, filename
);
191 tmpl
= template_load(filename
);
193 tmpl_list
= g_slist_insert_sorted(tmpl_list
, tmpl
, tmpl_compare
);
203 #define TRY(func) { \
206 g_warning("failed to write template to file"); \
207 if (fp) claws_fclose(fp); \
208 if (new) claws_unlink(new); \
215 #define TRY_NO_CLOSE(func) { \
218 g_warning("failed to write template to file"); \
219 if (new) claws_unlink(new); \
226 static void template_write_config(GSList
*tmpl_list
)
234 debug_print("%s:%d writing templates\n", __FILE__
, __LINE__
);
236 path
= get_template_dir();
238 if (!is_dir_exist(path
)) {
239 if (is_file_exist(path
)) {
240 g_warning("file '%s' already exists", path
);
243 if (make_dir(path
) < 0)
247 for (cur
= tmpl_list
, tmpl_num
= 1; cur
!= NULL
;
248 cur
= cur
->next
, tmpl_num
++) {
249 gchar
*filename
, *new = NULL
;
253 filename
= g_strconcat(path
, G_DIR_SEPARATOR_S
,
254 itos(tmpl_num
), NULL
);
256 if (is_file_exist(filename
)) {
257 new = g_strconcat(filename
, ".new", NULL
);
260 if ((fp
= claws_fopen(new?new:filename
, "wb")) == NULL
) {
261 FILE_OP_ERROR(new?new:filename
, "claws_fopen");
267 TRY(fprintf(fp
, "Name: %s\n", tmpl
->name
) > 0);
268 if (tmpl
->subject
&& *tmpl
->subject
!= '\0')
269 TRY(fprintf(fp
, "Subject: %s\n", tmpl
->subject
) > 0);
270 if (tmpl
->from
&& *tmpl
->from
!= '\0')
271 TRY(fprintf(fp
, "From: %s\n", tmpl
->from
) > 0);
272 if (tmpl
->to
&& *tmpl
->to
!= '\0')
273 TRY(fprintf(fp
, "To: %s\n", tmpl
->to
) > 0);
274 if (tmpl
->cc
&& *tmpl
->cc
!= '\0')
275 TRY(fprintf(fp
, "Cc: %s\n", tmpl
->cc
) > 0);
276 if (tmpl
->bcc
&& *tmpl
->bcc
!= '\0')
277 TRY(fprintf(fp
, "Bcc: %s\n", tmpl
->bcc
) > 0);
278 if (tmpl
->replyto
&& *tmpl
->replyto
!= '\0')
279 TRY(fprintf(fp
, "Reply-To: %s\n", tmpl
->replyto
) > 0);
281 TRY(claws_fputs("\n", fp
) != EOF
);
283 if (tmpl
->value
&& *tmpl
->value
!= '\0') {
284 TRY(claws_fwrite(tmpl
->value
, sizeof(gchar
), strlen(tmpl
->value
), fp
) == strlen(tmpl
->value
));
286 TRY(claws_fwrite("", sizeof(gchar
), 1, fp
) == 1);
288 TRY_NO_CLOSE(claws_safe_fclose(fp
) != EOF
);
291 if (rename_force(new, filename
) < 0) {
292 FILE_OP_ERROR(new, "rename");
299 /* remove other templates */
301 gchar
*filename
= g_strconcat(path
, G_DIR_SEPARATOR_S
,
302 itos(tmpl_num
), NULL
);
303 if (is_file_exist(filename
)) {
304 debug_print("removing old template %d\n", tmpl_num
);
305 claws_unlink(filename
);
315 GSList
*template_get_config(void)
318 template_list
= template_read_config();
320 return template_list
;
323 void template_set_config(GSList
*tmpl_list
)
325 template_clear_config(template_list
);
326 template_write_config(tmpl_list
);
327 template_list
= tmpl_list
;