mail-notification

Fork of Jean-Yves Lefort's mail-notification, a tray icon to notify of new mail
git clone https://code.djc.id.au/git/mail-notification/

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 }