src/mn-yahoo-mailbox.gob (7646B) - raw
1 /* 2 * Mail Notification 3 * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program 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 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 %headertop{ 21 #include "mn-webmail-mailbox.h" 22 %} 23 24 %{ 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 #include <fcntl.h> 28 #include <errno.h> 29 #include <unistd.h> 30 #include <string.h> 31 #include <glib/gi18n.h> 32 #include "mn-webmail-mailbox-private.h" 33 #include "mn-stock.h" 34 #include "mn-conf.h" 35 #include "mn-util.h" 36 %} 37 38 class MN:Yahoo:Mailbox from MN:Webmail:Mailbox 39 { 40 class_init (class) 41 { 42 MN_MAILBOX_CLASS(class)->type = "yahoo"; 43 44 /* 5 minutes is a good default */ 45 MN_MAILBOX_CLASS(class)->default_check_delay = 60 * 5; 46 47 MN_WEBMAIL_MAILBOX_CLASS(class)->default_domain = "yahoo.com"; 48 } 49 50 init (self) 51 { 52 mn_mailbox_set_format(MN_MAILBOX(self), "Yahoo! Mail"); 53 mn_mailbox_set_stock_id(MN_MAILBOX(self), MN_STOCK_YAHOO); 54 } 55 56 private char * 57 create_cookies_file (GError **err) 58 { 59 char *filename; 60 61 /* 62 * If the file already exists, ensure it has the proper 63 * permissions. Otherwise, create it with the proper permissions. 64 */ 65 66 filename = g_build_filename(mn_conf_dot_dir, "yahoo-cookies", NULL); 67 if (g_file_test(filename, G_FILE_TEST_EXISTS)) 68 { 69 if (chmod(filename, S_IRUSR | S_IWUSR) < 0) 70 { 71 g_set_error(err, 0, 0, _("unable to change the permissions of %s: %s"), filename, g_strerror(errno)); 72 goto error; 73 } 74 } 75 else 76 { 77 int fd; 78 79 fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 80 if (fd < 0) 81 { 82 g_set_error(err, 0, 0, _("unable to create %s: %s"), filename, g_strerror(errno)); 83 goto error; 84 } 85 close(fd); 86 } 87 88 return filename; 89 90 error: 91 g_free(filename); 92 return NULL; 93 } 94 95 private gboolean 96 can_convert (const char *str (check null), 97 const char *encoding (check null)) 98 { 99 char *converted; 100 gboolean can; 101 102 converted = g_convert(str, -1, encoding, "UTF-8", NULL, NULL, NULL); 103 can = converted != NULL; 104 g_free(converted); 105 106 return can; 107 } 108 109 private const char * 110 get_config_file_encoding (const char *folder (check null)) 111 { 112 /* 113 * fetchyahoo does not seem to deal with the folder name encoding 114 * at all, and Yahoo apparently uses ISO8859-1 when possible, and 115 * UTF-8 otherwise. 116 */ 117 if (self_can_convert(folder, "ISO8859-1")) 118 return "ISO8859-1"; 119 else 120 return "UTF-8"; 121 } 122 123 private char * 124 create_config_file (self, 125 const char *spool_file (check null), 126 const char *cookies_file (check null), 127 GError **err) 128 { 129 GString *contents; 130 char *filename; 131 132 contents = g_string_new(NULL); 133 134 g_string_append_printf(contents, 135 "username = %s\n" 136 "password = %s\n" 137 "folder = %s\n" 138 "spool = %s\n" 139 "cookie-file = %s\n" 140 "new-messages-only = 1\n" 141 "no-delete = 1\n" 142 "leave-unread = 1\n", 143 MN_AUTHENTICATED_MAILBOX(self)->username, 144 MN_AUTHENTICATED_MAILBOX(self)->runtime_password, 145 MN_WEBMAIL_MAILBOX(self)->folder, 146 spool_file, 147 cookies_file); 148 149 if (mn_conf_get_bool(MN_CONF_SYSTEM_HTTP_PROXY_USE_HTTP_PROXY)) 150 { 151 char *host; 152 153 host = mn_conf_get_string(MN_CONF_SYSTEM_HTTP_PROXY_HOST); 154 if (host && *host) 155 { 156 g_string_append_printf(contents, 157 "use-proxy = 1\n" 158 "proxy-host = %s\n" 159 "proxy-port = %i\n", 160 host, 161 mn_conf_get_int(MN_CONF_SYSTEM_HTTP_PROXY_PORT)); 162 163 if (mn_conf_get_bool(MN_CONF_SYSTEM_HTTP_PROXY_USE_AUTHENTICATION)) 164 { 165 char *user; 166 char *password; 167 168 user = mn_conf_get_string(MN_CONF_SYSTEM_HTTP_PROXY_AUTHENTICATION_USER); 169 password = mn_conf_get_string(MN_CONF_SYSTEM_HTTP_PROXY_AUTHENTICATION_PASSWORD); 170 171 if (user && *user && password && *password) 172 g_string_append_printf(contents, 173 "proxy-username = %s\n" 174 "proxy-password = %s\n", 175 user, 176 password); 177 178 g_free(user); 179 g_free(password); 180 } 181 } 182 g_free(host); 183 } 184 185 mn_webmail_mailbox_print_config(MN_WEBMAIL_MAILBOX(self), contents->str); 186 filename = mn_webmail_mailbox_write_temporary_file(contents->str, self_get_config_file_encoding(MN_WEBMAIL_MAILBOX(self)->folder), err); 187 188 g_string_free(contents, TRUE); 189 190 return filename; 191 } 192 193 override (MN:Webmail:Mailbox) char * 194 get_error_message (MNWebmailMailbox *mailbox, 195 const char *helper_stdout, 196 const char *helper_stderr, 197 gboolean *is_auth_failure) 198 { 199 if (helper_stderr) 200 { 201 char **lines; 202 int i; 203 char *message = NULL; 204 205 lines = g_strsplit(helper_stderr, "\n", 0); 206 for (i = 0; lines[i]; i++) 207 if (g_str_has_prefix(lines[i], "Failed: ")) 208 { 209 char *escaped; 210 211 if (mn_ascii_strcasestr(lines[i], "wrong password") 212 || mn_ascii_strcasestr(lines[i], "invalid ID") 213 || (mn_ascii_strcasestr(lines[i], "Yahoo user") 214 && mn_ascii_strcasestr(lines[i], "does not exist"))) 215 *is_auth_failure = TRUE; 216 217 escaped = mn_utf8_escape(lines[i] + 8); 218 message = g_strdup_printf(_("\"%s\""), escaped); 219 g_free(escaped); 220 221 break; 222 } 223 g_strfreev(lines); 224 225 if (message) 226 return message; 227 228 if (mn_ascii_strcasestr(helper_stderr, "an image of text")) 229 return g_strdup(_("delay between mail checks too small")); 230 } 231 232 return NULL; 233 } 234 235 private gboolean 236 run_fetchyahoo (self, const char *config_file (check null), GError **err) 237 { 238 char *command; 239 gboolean status; 240 241 command = g_strdup_printf("fetchyahoo --configfile=%s", config_file); 242 status = mn_webmail_mailbox_run_helper(MN_WEBMAIL_MAILBOX(self), "fetchyahoo", command, err); 243 g_free(command); 244 245 return status; 246 } 247 248 override (MN:Webmail:Mailbox) gboolean 249 webmail_check (MNWebmailMailbox *mailbox, GError **err) 250 { 251 Self *self = SELF(mailbox); 252 char *spool_file; 253 char *cookies_file; 254 char *config_file = NULL; 255 gboolean status = FALSE; 256 257 /* 258 * We create an empty spool file beforehand to make sure it is not 259 * world-readable. 260 */ 261 spool_file = mn_webmail_mailbox_create_spool_file(err); 262 if (! spool_file) 263 return FALSE; 264 265 /* 266 * Likewise, we create an empty cookies file beforehand to make 267 * sure it is not world-readable. 268 */ 269 cookies_file = self_create_cookies_file(err); 270 if (! cookies_file) 271 goto end; 272 273 /* 274 * We create a config file rather than use command line arguments 275 * because for obvious reasons, we must not pass the password on 276 * the command line. 277 */ 278 config_file = self_create_config_file(self, spool_file, cookies_file, err); 279 if (! config_file) 280 goto end; 281 282 if (! self_run_fetchyahoo(self, config_file, err)) 283 goto end; 284 285 if (! mn_webmail_mailbox_read_spool_file(mailbox, spool_file, err)) 286 goto end; 287 288 status = TRUE; 289 290 end: 291 unlink(spool_file); 292 g_free(spool_file); 293 294 g_free(cookies_file); 295 296 if (config_file) 297 { 298 unlink(config_file); 299 g_free(config_file); 300 } 301 302 return status; 303 } 304 }