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-keyring.c (5916B) - 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 #include "mn-keyring.h"
     21 
     22 typedef struct
     23 {
     24   GMutex	*mutex;
     25   GCond		*cond;
     26   gboolean	done;
     27 } Request;
     28 
     29 typedef struct
     30 {
     31   Request			request;
     32 
     33   const char			*username;
     34   const char			*domain;
     35   const char			*server;
     36   const char			*protocol;
     37   const char			*authtype;
     38   int				port;
     39 
     40   MNKeyringRequestCallback	request_callback;
     41   gpointer			data;
     42 
     43   char				*password;
     44 } GetPasswordInfo;
     45 
     46 typedef struct
     47 {
     48   Request			request;
     49 
     50   const char			*keyring;
     51   const char			*username;
     52   const char			*domain;
     53   const char			*server;
     54   const char			*protocol;
     55   const char			*authtype;
     56   int				port;
     57   const char			*password;
     58 
     59   MNKeyringRequestCallback	request_callback;
     60   gpointer			data;
     61 
     62   GnomeKeyringResult		result;
     63   guint32			item_id;
     64 } SetPasswordInfo;
     65 
     66 static void
     67 request_perform (Request *request, GSourceFunc perform_callback, gpointer data)
     68 {
     69   g_return_if_fail(request != NULL);
     70   g_return_if_fail(perform_callback != NULL);
     71 
     72   request->mutex = g_mutex_new();
     73   request->cond = g_cond_new();
     74   request->done = FALSE;
     75 
     76   /*
     77    * Work around http://bugzilla.gnome.org/show_bug.cgi?id=474695 by
     78    * calling the gnome-keyring async function from a main loop
     79    * callback.
     80    */
     81   g_idle_add(perform_callback, data);
     82 
     83   g_mutex_lock(request->mutex);
     84 
     85   if (! request->done)
     86     g_cond_wait(request->cond, request->mutex);
     87 
     88   g_mutex_unlock(request->mutex);
     89 
     90   g_mutex_free(request->mutex);
     91   g_cond_free(request->cond);
     92 }
     93 
     94 static void
     95 request_signal (Request *request)
     96 {
     97   g_return_if_fail(request != NULL);
     98 
     99   g_mutex_lock(request->mutex);
    100 
    101   request->done = TRUE;
    102   g_cond_signal(request->cond);
    103 
    104   g_mutex_unlock(request->mutex);
    105 }
    106 
    107 static void
    108 get_password_sync_cb (GnomeKeyringResult result,
    109 		      GList *list,
    110 		      gpointer data)
    111 {
    112   GetPasswordInfo *info = data;
    113 
    114   info->request_callback(NULL, info->data);
    115 
    116   if (result == GNOME_KEYRING_RESULT_OK && list)
    117     {
    118       GnomeKeyringNetworkPasswordData *password_data = list->data;
    119       info->password = g_strdup(password_data->password);
    120     }
    121 
    122   request_signal(&info->request);
    123 }
    124 
    125 static gboolean
    126 get_password_sync_perform_cb (gpointer data)
    127 {
    128   GetPasswordInfo *info = data;
    129   gpointer request;
    130 
    131   request = gnome_keyring_find_network_password(info->username,
    132 						info->domain,
    133 						info->server,
    134 						NULL,
    135 						info->protocol,
    136 						info->authtype,
    137 						info->port,
    138 						get_password_sync_cb,
    139 						info,
    140 						NULL);
    141 
    142   info->request_callback(request, info->data);
    143 
    144   return FALSE;			/* remove source */
    145 }
    146 
    147 char *
    148 mn_keyring_get_password_sync (const char *username,
    149 			      const char *domain,
    150 			      const char *server,
    151 			      const char *protocol,
    152 			      const char *authtype,
    153 			      int port,
    154 			      MNKeyringRequestCallback request_callback,
    155 			      gpointer data)
    156 {
    157   GetPasswordInfo info;
    158 
    159   g_return_val_if_fail(request_callback != NULL, NULL);
    160 
    161   info.username = username;
    162   info.domain = domain;
    163   info.server = server;
    164   info.protocol = protocol;
    165   info.authtype = authtype;
    166   info.port = port;
    167 
    168   info.request_callback = request_callback;
    169   info.data = data;
    170 
    171   info.password = NULL;
    172 
    173   request_perform(&info.request, get_password_sync_perform_cb, &info);
    174 
    175   return info.password;
    176 }
    177 
    178 static void
    179 set_password_sync_cb (GnomeKeyringResult result,
    180 		      guint32 item_id,
    181 		      gpointer data)
    182 {
    183   SetPasswordInfo *info = data;
    184 
    185   info->request_callback(NULL, info->data);
    186 
    187   info->result = result;
    188   info->item_id = item_id;
    189 
    190   request_signal(&info->request);
    191 }
    192 
    193 static gboolean
    194 set_password_sync_perform_cb (gpointer data)
    195 {
    196   SetPasswordInfo *info = data;
    197   gpointer request;
    198 
    199   request = gnome_keyring_set_network_password(info->keyring,
    200 					       info->username,
    201 					       info->domain,
    202 					       info->server,
    203 					       NULL,
    204 					       info->protocol,
    205 					       info->authtype,
    206 					       info->port,
    207 					       info->password,
    208 					       set_password_sync_cb,
    209 					       info,
    210 					       NULL);
    211 
    212   info->request_callback(request, info->data);
    213 
    214   return FALSE;			/* remove source */
    215 }
    216 
    217 GnomeKeyringResult
    218 mn_keyring_set_password_sync (const char *keyring,
    219 			      const char *username,
    220 			      const char *domain,
    221 			      const char *server,
    222 			      const char *protocol,
    223 			      const char *authtype,
    224 			      int port,
    225 			      const char *password,
    226 			      guint32 *item_id,
    227 			      MNKeyringRequestCallback request_callback,
    228 			      gpointer data)
    229 {
    230   SetPasswordInfo info;
    231 
    232   g_return_val_if_fail(password != NULL, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
    233   g_return_val_if_fail(item_id != NULL, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
    234   g_return_val_if_fail(request_callback != NULL, GNOME_KEYRING_RESULT_BAD_ARGUMENTS);
    235 
    236   info.keyring = keyring;
    237   info.username = username;
    238   info.domain = domain;
    239   info.server = server;
    240   info.protocol = protocol;
    241   info.authtype = authtype;
    242   info.port = port;
    243   info.password = password;
    244 
    245   info.request_callback = request_callback;
    246   info.data = data;
    247 
    248   request_perform(&info.request, set_password_sync_perform_cb, &info);
    249 
    250   if (info.result == GNOME_KEYRING_RESULT_OK)
    251     *item_id = info.item_id;
    252 
    253   return info.result;
    254 }