2004-11-26 [colin] 0.9.12cvs173.1
[claws.git] / src / common / template.c
1 /*
2  * Sylpheed templates subsystem 
3  * Copyright (C) 2001 Alexander Barinov
4  * Copyright (C) 2001 Hiroyuki Yamamoto
5  *
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 2 of the License, or
9  * (at your option) any later version.
10  *
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.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21 #include "defs.h"
22
23 #include <glib.h>
24 #include <stdio.h>
25 #include <dirent.h>
26 #include <sys/stat.h>
27 #include <ctype.h>
28
29 #include "intl.h"
30 #include "utils.h"
31 #include "template.h"
32 #include "../codeconv.h"
33
34 static GSList *template_list;
35
36 static Template *template_load(gchar *filename)
37 {
38         Template *tmpl;
39         FILE *fp;
40         gchar buf[BUFFSIZE];
41         gint bytes_read;
42 #warning FIXME_GTK2
43         const gchar *src_codeset = conv_get_current_charset_str();
44         const gchar *dest_codeset = CS_UTF_8;
45
46         if ((fp = fopen(filename, "rb")) == NULL) {
47                 FILE_OP_ERROR(filename, "fopen");
48                 return NULL;
49         }
50
51         tmpl = g_new(Template, 1);
52         tmpl->name = NULL;
53         tmpl->subject = NULL;
54         tmpl->to = NULL;
55         tmpl->cc = NULL;        
56         tmpl->bcc = NULL;       
57         tmpl->value = NULL;
58
59         while (fgets(buf, sizeof(buf), fp) != NULL) {
60                 gchar *tmp = NULL;
61
62                 if (buf[0] == '\n')
63                         break;
64                 else if (!g_ascii_strncasecmp(buf, "Name:", 5)) {
65                         tmp = conv_codeset_strdup(buf + 5,
66                                                   src_codeset,
67                                                   dest_codeset);
68                         tmpl->name = tmp ? g_strstrip(tmp) : g_strdup(buf + 5);
69                 } else if (!g_ascii_strncasecmp(buf, "Subject:", 8)) {
70                         tmp = conv_codeset_strdup(buf + 8,
71                                                   src_codeset,
72                                                   dest_codeset);
73                         tmpl->subject = tmp ? g_strstrip(tmp) : g_strdup(buf + 8);
74                 } else if (!g_ascii_strncasecmp(buf, "To:", 3)) {
75                         tmp = conv_codeset_strdup(buf + 3,
76                                                   src_codeset,
77                                                   dest_codeset);
78                         tmpl->to = tmp ? g_strstrip(tmp) : g_strdup(buf + 3);
79                 } else if (!g_ascii_strncasecmp(buf, "Cc:", 3)) {
80                         tmp = conv_codeset_strdup(buf + 3,
81                                                   src_codeset,
82                                                   dest_codeset);
83                         tmpl->cc = tmp ? g_strstrip(tmp) : g_strdup(buf + 3);
84                 } else if (!g_ascii_strncasecmp(buf, "Bcc:", 4)) {
85                         tmp = conv_codeset_strdup(buf + 4,
86                                                   src_codeset,
87                                                   dest_codeset);
88                         tmpl->bcc = tmp ? g_strstrip(tmp) : g_strdup(buf + 4);
89                 }
90         }
91
92         if (!tmpl->name) {
93                 g_warning("wrong template format\n");
94                 template_free(tmpl);
95                 return NULL;
96         }
97
98         if ((bytes_read = fread(buf, 1, sizeof(buf), fp)) == 0) {
99                 if (ferror(fp)) {
100                         FILE_OP_ERROR(filename, "fread");
101                         template_free(tmpl);
102                         return NULL;
103                 }
104         }
105         fclose(fp);
106         buf[bytes_read] = '\0';
107         tmpl->value = conv_codeset_strdup(buf, src_codeset, dest_codeset);
108         if (!tmpl->value)
109                 tmpl->value = g_strdup(buf);
110
111         return tmpl;
112 }
113
114 void template_free(Template *tmpl)
115 {
116         g_free(tmpl->name);
117         g_free(tmpl->subject);
118         g_free(tmpl->to);
119         g_free(tmpl->cc);
120         g_free(tmpl->bcc);              
121         g_free(tmpl->value);
122         g_free(tmpl);
123 }
124
125 void template_clear_config(GSList *tmpl_list)
126 {
127         GSList *cur;
128         Template *tmpl;
129
130         for (cur = tmpl_list; cur != NULL; cur = cur->next) {
131                 tmpl = (Template *)cur->data;
132                 template_free(tmpl);
133         }
134         g_slist_free(tmpl_list);
135 }
136
137 GSList *template_read_config(void)
138 {
139         const gchar *path;
140         gchar *filename;
141         DIR *dp;
142         struct dirent *de;
143         struct stat s;
144         Template *tmpl;
145         GSList *tmpl_list = NULL;
146
147         path = get_template_dir();
148         debug_print("%s:%d reading templates dir %s\n",
149                     __FILE__, __LINE__, path);
150
151         if (!is_dir_exist(path)) {
152                 if (make_dir(path) < 0)
153                         return NULL;
154         }
155
156         if ((dp = opendir(path)) == NULL) {
157                 FILE_OP_ERROR(path, "opendir");
158                 return NULL;
159         }
160
161         while ((de = readdir(dp)) != NULL) {
162                 if (*de->d_name == '.') continue;
163
164                 filename = g_strconcat(path, G_DIR_SEPARATOR_S, de->d_name, NULL);
165
166                 if (stat(filename, &s) != 0 || !S_ISREG(s.st_mode) ) {
167                         debug_print("%s:%d %s is not an ordinary file\n",
168                                     __FILE__, __LINE__, filename);
169                         continue;
170                 }
171
172                 tmpl = template_load(filename);
173                 if (tmpl)
174                         tmpl_list = g_slist_append(tmpl_list, tmpl);
175                 g_free(filename);
176         }
177
178         closedir(dp);
179
180         return tmpl_list;
181 }
182
183 void template_write_config(GSList *tmpl_list)
184 {
185         const gchar *path;
186         GSList *cur;
187         Template *tmpl;
188         FILE *fp;
189         gint tmpl_num;
190
191         debug_print("%s:%d writing templates\n", __FILE__, __LINE__);
192
193         path = get_template_dir();
194
195         if (!is_dir_exist(path)) {
196                 if (is_file_exist(path)) {
197                         g_warning("file %s already exists\n", path);
198                         return;
199                 }
200                 if (make_dir(path) < 0)
201                         return;
202         }
203
204         remove_all_files(path);
205
206         for (cur = tmpl_list, tmpl_num = 1; cur != NULL;
207              cur = cur->next, tmpl_num++) {
208 #warning FIXME_GTK2
209                 const gchar *src_codeset = CS_UTF_8;
210                 const gchar *dest_codeset = conv_get_current_charset_str();
211                 gchar *tmp = NULL;
212                 gchar *filename;
213
214                 tmpl = cur->data;
215
216                 filename = g_strconcat(path, G_DIR_SEPARATOR_S,
217                                        itos(tmpl_num), NULL);
218
219                 if ((fp = fopen(filename, "wb")) == NULL) {
220                         FILE_OP_ERROR(filename, "fopen");
221                         g_free(filename);
222                         return;
223                 }
224
225                 tmp = conv_codeset_strdup(tmpl->name, src_codeset, dest_codeset);
226                 if (!tmp)
227                         tmp = g_strdup(tmpl->name);
228                 fprintf(fp, "Name: %s\n", tmp ? tmp : "");
229                 g_free(tmp);
230
231                 if (tmpl->subject && *tmpl->subject != '\0') {
232                         tmp = conv_codeset_strdup(tmpl->subject,
233                                                   src_codeset, dest_codeset);
234                         if (!tmp)
235                                 tmp = g_strdup(tmpl->subject);
236                         fprintf(fp, "Subject: %s\n", tmp);
237                         g_free(tmp);
238                 }
239
240                 if (tmpl->to && *tmpl->to != '\0') {
241                         tmp = conv_codeset_strdup(tmpl->to,
242                                                   src_codeset, dest_codeset);
243                         if (!tmp)
244                                 tmp = g_strdup(tmpl->to);
245                         fprintf(fp, "To: %s\n", tmp);
246                         g_free(tmp);
247                 }
248
249                 if (tmpl->cc && *tmpl->cc != '\0') {
250                         tmp = conv_codeset_strdup(tmpl->cc,
251                                                   src_codeset, dest_codeset);
252                         if (!tmp)
253                                 tmp = g_strdup(tmpl->cc);
254                         fprintf(fp, "Cc: %s\n", tmp);
255                         g_free(tmp);
256                 }
257
258                 if (tmpl->bcc && *tmpl->bcc != '\0') {
259                         tmp = conv_codeset_strdup(tmpl->bcc,
260                                                   src_codeset, dest_codeset);
261                         if (!tmp)
262                                 tmp = g_strdup(tmpl->bcc);
263                         fprintf(fp, "Bcc: %s\n", tmp);
264                         g_free(tmp);
265                 }
266
267                 fputs("\n", fp);
268                 tmp = conv_codeset_strdup(tmpl->value,
269                                           src_codeset, dest_codeset);
270                 if (!tmp)
271                         tmp = g_strdup(tmpl->value);
272                 fwrite(tmp, sizeof(gchar) * strlen(tmp), 1, fp);
273                 g_free(tmp);
274                 fclose(fp);
275         }
276 }
277
278 GSList *template_get_config(void)
279 {
280         if (!template_list)
281                 template_list = template_read_config();
282
283         return template_list;
284 }
285
286 void template_set_config(GSList *tmpl_list)
287 {
288         template_clear_config(template_list);
289         template_write_config(tmpl_list);
290         template_list = tmpl_list;
291 }