1 /*
2 * xfce4-mailwatch-plugin - a mail notification applet for the xfce4 panel
3 * Copyright (c) 2005-2008 Brian Tarricone <bjt23@cornell.edu>
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; version 2 of the License ONLY.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <stdio.h>
24
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32
33 #ifdef HAVE_STRING_H
34 #include <string.h>
35 #endif
36
37 #ifdef HAVE_SYS_TYPES_H
38 #include <sys/types.h>
39 #endif
40
41 #ifdef HAVE_SYS_SOCKET_H
42 #include <sys/socket.h>
43 #endif
44
45 #if HAVE_NETINET_IN_H
46 #include <netinet/in.h>
47 #endif
48
49 #ifdef HAVE_NETDB_H
50 #include <netdb.h>
51 #endif
52
53 #ifdef HAVE_SYS_SELECT_H
54 #include <sys/select.h>
55 #endif
56
57 #ifdef HAVE_SYS_WAIT_H
58 #include <sys/wait.h>
59 #endif
60
61 #ifdef HAVE_FCNTL_H
62 #include <fcntl.h>
63 #endif
64
65 #ifdef HAVE_ERRNO_H
66 #include <errno.h>
67 #endif
68
69 #ifndef MSG_NOSIGNAL
70 #define MSG_NOSIGNAL 0
71 #endif
72
73 #include <glib.h>
74 #include <gtk/gtk.h>
75
76 #include <libxfce4util/libxfce4util.h>
77 #include <libxfce4ui/libxfce4ui.h>
78
79 #include "mailwatch-utils.h"
80 #include "mailwatch.h"
81 #include "mailwatch-net-conn.h"
82
83 #define BORDER 8
84 #define GMAIL_HOST "mail.google.com"
85 #define GMAIL_ATOMURI "/mail/feed/atom"
86 #define XFCE_MAILWATCH_GMAIL_MAILBOX(ptr) ((XfceMailwatchGMailMailbox *)ptr)
87
88 typedef struct
89 {
90 XfceMailwatchMailbox mailbox;
91
92 GMutex config_mx;
93
94 gchar *username;
95 gchar *password;
96 guint timeout;
97
98 XfceMailwatch *mailwatch;
99
100 /* current connection state */
101 gint running;
102 gpointer th;
103 XfceMailwatchNetConn *net_conn;
104 guint check_id;
105 } XfceMailwatchGMailMailbox;
106
107
108 static gboolean
gmail_should_continue(XfceMailwatchNetConn * net_conn,gpointer user_data)109 gmail_should_continue(XfceMailwatchNetConn *net_conn,
110 gpointer user_data)
111 {
112 XfceMailwatchGMailMailbox *gmailbox = user_data;
113 return g_atomic_int_get(&gmailbox->running);
114 }
115
116 static gssize
gmail_send(XfceMailwatchGMailMailbox * gmailbox,const gchar * buf)117 gmail_send(XfceMailwatchGMailMailbox *gmailbox, const gchar *buf)
118 {
119 GError *error = NULL;
120 gssize sent;
121
122 sent = xfce_mailwatch_net_conn_send_data(gmailbox->net_conn,
123 (const guchar *)buf, -1,
124 &error);
125 if(sent < 0) {
126 xfce_mailwatch_log_message(gmailbox->mailwatch,
127 XFCE_MAILWATCH_MAILBOX(gmailbox),
128 XFCE_MAILWATCH_LOG_ERROR,
129 error->message);
130 g_error_free(error);
131 }
132
133 return sent;
134 }
135
136 static gssize
gmail_recv(XfceMailwatchGMailMailbox * gmailbox,gchar * buf,gsize len)137 gmail_recv(XfceMailwatchGMailMailbox *gmailbox, gchar *buf, gsize len)
138 {
139 GError *error = NULL;
140 gssize recvd;
141
142 recvd = xfce_mailwatch_net_conn_recv_data(gmailbox->net_conn,
143 (guchar *)buf, len, &error);
144 if(recvd < 0) {
145 xfce_mailwatch_log_message(gmailbox->mailwatch,
146 XFCE_MAILWATCH_MAILBOX(gmailbox),
147 XFCE_MAILWATCH_LOG_ERROR,
148 error->message);
149 g_error_free(error);
150 }
151 buf[recvd] = 0;
152
153 return recvd;
154 }
155
156 static gboolean
gmail_connect(XfceMailwatchGMailMailbox * gmailbox,gint * port)157 gmail_connect(XfceMailwatchGMailMailbox *gmailbox, gint *port)
158 {
159 GError *error = NULL;
160
161 TRACE("entering");
162
163 g_return_val_if_fail(port, FALSE);
164
165 gmailbox->net_conn = xfce_mailwatch_net_conn_new(GMAIL_HOST, "https");
166 xfce_mailwatch_net_conn_set_should_continue_func(gmailbox->net_conn,
167 gmail_should_continue,
168 gmailbox);
169
170 if(xfce_mailwatch_net_conn_connect(gmailbox->net_conn, &error)) {
171 *port = xfce_mailwatch_net_conn_get_port(gmailbox->net_conn);
172 return TRUE;
173 } else {
174 xfce_mailwatch_log_message(gmailbox->mailwatch,
175 XFCE_MAILWATCH_MAILBOX(gmailbox),
176 XFCE_MAILWATCH_LOG_ERROR,
177 "%s", error->message);
178 g_error_free(error);
179 return FALSE;
180 }
181 }
182
183 static gboolean
gmail_check_atom_feed(XfceMailwatchGMailMailbox * gmailbox,const gchar * username,const gchar * password,guint * new_messages)184 gmail_check_atom_feed(XfceMailwatchGMailMailbox *gmailbox,
185 const gchar *username,
186 const gchar *password,
187 guint *new_messages)
188 {
189 #define BUFSIZE 8191
190 gboolean ret = FALSE, first_recv = TRUE;
191 GError *error = NULL;
192 gchar buf[BUFSIZE+1], *base64_creds, *p, *q;
193 gint bin, port = 0, respcode, tmp;
194
195 if(!gmail_connect(gmailbox, &port)) {
196 DBG("failed to connect to gmail server");
197 return FALSE;
198 }
199
200 if(!xfce_mailwatch_net_conn_make_secure(gmailbox->net_conn, &error)) {
201 xfce_mailwatch_log_message(gmailbox->mailwatch,
202 XFCE_MAILWATCH_MAILBOX(gmailbox),
203 XFCE_MAILWATCH_LOG_ERROR,
204 _("TLS handshake failed: %s"),
205 error->message);
206 g_error_free(error);
207 goto cleanup;
208 }
209
210 g_snprintf(buf, BUFSIZE, "%s:%s", username, password);
211 base64_creds = g_base64_encode((guchar *)buf, strlen(buf));
212 if(!base64_creds) {
213 DBG("failed to base64 enc credentials");
214 goto cleanup;
215 }
216
217 g_snprintf(buf, BUFSIZE, "GET %s HTTP/1.1\r\n" \
218 "Host: %s:%d\r\n" \
219 "User-Agent: %s/%s\r\n" \
220 "Authorization: Basic %s\r\n" \
221 "Connection: close\r\n" \
222 "\r\n",
223 GMAIL_ATOMURI, GMAIL_HOST, port, PACKAGE, VERSION, base64_creds);
224 g_free(base64_creds);
225
226 if(gmail_send(gmailbox, buf) != (gssize)strlen(buf)) {
227 DBG("failed to send req");
228 goto cleanup;
229 }
230
231 for(;;) {
232 if(!xfce_mailwatch_net_conn_should_continue(gmailbox->net_conn))
233 break;
234
235 bin = gmail_recv(gmailbox, buf, BUFSIZE);
236 if(bin <= 0) {
237 DBG("failed to recv response (%d)", bin);
238 break;
239 }
240
241 if(first_recv) {
242 p = strstr(buf, " ");
243 DBG("got first space");
244 if(p) {
245 q = strstr(p+1, " ");
246 if(q) {
247 DBG("got second space");
248 *q = 0;
249 respcode = atoi(p+1);
250 DBG("response code is %d", respcode);
251 if(respcode != 200) {
252 if(respcode == 403 || respcode == 401) {
253 xfce_mailwatch_log_message(gmailbox->mailwatch,
254 XFCE_MAILWATCH_MAILBOX(gmailbox),
255 XFCE_MAILWATCH_LOG_ERROR,
256 _("Received HTTP response code %d. The most likely reason for this is that your GMail username or password is incorrect."),
257 respcode);
258 } else {
259 xfce_mailwatch_log_message(gmailbox->mailwatch,
260 XFCE_MAILWATCH_MAILBOX(gmailbox),
261 XFCE_MAILWATCH_LOG_ERROR,
262 _("Received HTTP response code %d, which should be 200. There may be a problem with GMail's servers, or they have incompatibly changed their authentication method or location of the new messages feed."),
263 respcode);
264 }
265 break;
266 }
267 *q = ' ';
268 }
269 }
270 first_recv = FALSE;
271 }
272
273 p = strstr(buf, "<fullcount>");
274 if(!p)
275 continue;
276
277 DBG("got opening <fullcount> tag: '%s'", p);
278
279 q = strstr(p+1, "<");
280 if(!q) {
281 gchar buf1[1024];
282 bin = gmail_recv(gmailbox, buf1, BUFSIZE);
283 if(bin <= 0) {
284 DBG("failed to recv response (%d)", bin);
285 break;
286 }
287
288 q = strstr(buf1, "<");
289 if(!q) {
290 DBG("can't find </fullcount> closing tag");
291 break;
292 }
293
294 memmove(buf, p, strlen(p));
295 memcpy(buf+strlen(p), buf1, strlen(buf1));
296 buf[strlen(p)+strlen(buf1)] = 0;
297 p = buf;
298 q = strstr(p+1, "<");
299 }
300
301 DBG("p=%p, q=%p", p, q);
302
303 *q = 0;
304 p += 11;
305 if(p >= q) {
306 DBG("that's not right...");
307 break;
308 }
309
310 tmp = atoi(p);
311 if(tmp < 0) {
312 DBG("new message count is <0");
313 break;
314 }
315
316 *new_messages = tmp;
317 ret = TRUE;
318 break;
319 }
320
321 cleanup:
322
323 if(gmailbox->net_conn) {
324 xfce_mailwatch_net_conn_destroy(gmailbox->net_conn);
325 gmailbox->net_conn = NULL;
326 }
327
328 return ret;
329 #undef BUFSIZE
330 }
331
332 static void
gmail_check_mail(XfceMailwatchGMailMailbox * gmailbox)333 gmail_check_mail(XfceMailwatchGMailMailbox *gmailbox)
334 {
335 #define BUFSIZE 1024
336 gchar username[BUFSIZE], password[BUFSIZE];
337 guint new_messages = 0;
338
339 g_mutex_lock(&(gmailbox->config_mx));
340
341 if(!gmailbox->username || !gmailbox->password) {
342 g_mutex_unlock(&(gmailbox->config_mx));
343 return;
344 }
345
346 g_strlcpy(username, gmailbox->username, BUFSIZE);
347 g_strlcpy(password, gmailbox->password, BUFSIZE);
348
349 g_mutex_unlock(&(gmailbox->config_mx));
350
351 if(gmail_check_atom_feed(gmailbox, username, password, &new_messages)) {
352 DBG("checked gmail, %u new messages", new_messages);
353 xfce_mailwatch_signal_new_messages(gmailbox->mailwatch,
354 XFCE_MAILWATCH_MAILBOX(gmailbox),
355 new_messages);
356 } else {
357 DBG("failed to connect to gmail server");
358 }
359 #undef BUFSIZE
360 }
361
362 static gpointer
gmail_check_mail_th(gpointer data)363 gmail_check_mail_th(gpointer data)
364 {
365 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(data);
366
367 while(!g_atomic_pointer_get(&gmailbox->th)
368 && g_atomic_int_get(&gmailbox->running))
369 {
370 g_thread_yield();
371 }
372
373 if(!g_atomic_int_get(&gmailbox->running)) {
374 g_atomic_pointer_set(&gmailbox->th, NULL);
375 return NULL;
376 }
377
378 gmail_check_mail(gmailbox);
379
380 g_atomic_pointer_set(&gmailbox->th, NULL);
381 return NULL;
382 }
383
384 static gboolean
gmail_check_mail_timeout(gpointer data)385 gmail_check_mail_timeout(gpointer data)
386 {
387 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(data);
388
389 GThread *th;
390
391 if(g_atomic_pointer_get(&gmailbox->th)) {
392 xfce_mailwatch_log_message(gmailbox->mailwatch,
393 XFCE_MAILWATCH_MAILBOX(gmailbox),
394 XFCE_MAILWATCH_LOG_WARNING,
395 _("Previous thread hasn't exited yet, not checking mail this time."));
396 return TRUE;
397 }
398
399 th = g_thread_try_new(NULL, gmail_check_mail_th, gmailbox, NULL);
400 g_atomic_pointer_set(&gmailbox->th, th);
401
402 return TRUE;
403 }
404
405 static XfceMailwatchMailbox *
gmail_mailbox_new(XfceMailwatch * mailwatch,XfceMailwatchMailboxType * type)406 gmail_mailbox_new(XfceMailwatch *mailwatch, XfceMailwatchMailboxType *type)
407 {
408 XfceMailwatchGMailMailbox *gmailbox = g_new0(XfceMailwatchGMailMailbox, 1);
409 gmailbox->mailbox.type = type;
410 gmailbox->mailwatch = mailwatch;
411 gmailbox->timeout = XFCE_MAILWATCH_DEFAULT_TIMEOUT;
412 g_mutex_init(&gmailbox->config_mx);
413
414 xfce_mailwatch_net_conn_init();
415
416 return (XfceMailwatchMailbox *)gmailbox;
417 }
418
419 static void
gmail_set_activated(XfceMailwatchMailbox * mailbox,gboolean activated)420 gmail_set_activated(XfceMailwatchMailbox *mailbox, gboolean activated)
421 {
422 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(mailbox);
423
424 if(activated == g_atomic_int_get(&gmailbox->running))
425 return;
426
427 if(activated) {
428 g_atomic_int_set(&gmailbox->running, TRUE);
429 gmailbox->check_id = g_timeout_add(gmailbox->timeout * 1000,
430 gmail_check_mail_timeout,
431 gmailbox);
432 } else {
433 g_atomic_int_set(&gmailbox->running, FALSE);
434 g_source_remove(gmailbox->check_id);
435 gmailbox->check_id = 0;
436 }
437 }
438
439 static void
gmail_force_update_cb(XfceMailwatchMailbox * mailbox)440 gmail_force_update_cb(XfceMailwatchMailbox *mailbox)
441 {
442 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(mailbox);
443
444 if(!g_atomic_pointer_get(&gmailbox->th)) {
445 gboolean restart = FALSE;
446
447 if(gmailbox->check_id) {
448 g_source_remove(gmailbox->check_id);
449 restart = TRUE;
450 }
451
452 gmail_check_mail_timeout(gmailbox);
453
454 if(restart) {
455 gmailbox->check_id = g_timeout_add(gmailbox->timeout * 1000,
456 gmail_check_mail_timeout,
457 gmailbox);
458 }
459 }
460 }
461
462 static gboolean
gmail_config_username_focus_out_cb(GtkWidget * w,GdkEventFocus * evt,gpointer user_data)463 gmail_config_username_focus_out_cb(GtkWidget *w,
464 GdkEventFocus *evt,
465 gpointer user_data)
466 {
467 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(user_data);
468
469 g_mutex_lock(&(gmailbox->config_mx));
470
471 g_free(gmailbox->username);
472 gmailbox->username = gtk_editable_get_chars(GTK_EDITABLE(w), 0, -1);
473
474 g_mutex_unlock(&(gmailbox->config_mx));
475
476 return FALSE;
477 }
478
479 static gboolean
gmail_config_password_focus_out_cb(GtkWidget * w,GdkEventFocus * evt,gpointer user_data)480 gmail_config_password_focus_out_cb(GtkWidget *w,
481 GdkEventFocus *evt,
482 gpointer user_data)
483 {
484 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(user_data);
485
486 g_mutex_lock(&(gmailbox->config_mx));
487
488 g_free(gmailbox->password);
489 gmailbox->password = gtk_editable_get_chars(GTK_EDITABLE(w), 0, -1);
490
491 g_mutex_unlock(&(gmailbox->config_mx));
492
493 return FALSE;
494 }
495
496 static gboolean
gmail_config_timeout_spinbutton_changed_cb(GtkSpinButton * sb,gpointer user_data)497 gmail_config_timeout_spinbutton_changed_cb(GtkSpinButton *sb,
498 gpointer user_data)
499 {
500 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(user_data);
501 guint value = (guint) gtk_spin_button_get_value_as_int(sb) * 60;
502
503 if(value == gmailbox->timeout)
504 return FALSE;
505
506 gmailbox->timeout = value;
507
508 if(g_atomic_int_get(&gmailbox->running)) {
509 /* probably shouldn't do this so frequently */
510 if(gmailbox->check_id)
511 g_source_remove(gmailbox->check_id);
512 gmailbox->check_id = g_timeout_add(gmailbox->timeout * 1000,
513 gmail_check_mail_timeout,
514 gmailbox);
515 }
516
517 return FALSE;
518 }
519
520 static GtkContainer *
gmail_get_setup_page(XfceMailwatchMailbox * mailbox)521 gmail_get_setup_page(XfceMailwatchMailbox *mailbox)
522 {
523 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(mailbox);
524 GtkWidget *vbox, *hbox, *lbl, *entry, *sbtn;
525 GtkSizeGroup *sg;
526
527 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, BORDER/2);
528 gtk_widget_show(vbox);
529
530 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
531
532 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BORDER/2);
533 gtk_widget_show(hbox);
534 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
535
536 lbl = gtk_label_new_with_mnemonic(_("_Username:"));
537 gtk_label_set_xalign(GTK_LABEL(lbl), 0.0);
538 gtk_widget_show(lbl);
539 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 0);
540 gtk_size_group_add_widget(sg, lbl);
541
542 entry = gtk_entry_new();
543 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
544 if(gmailbox->username)
545 gtk_entry_set_text(GTK_ENTRY(entry), gmailbox->username);
546 gtk_widget_show(entry);
547 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
548 g_signal_connect(G_OBJECT(entry), "focus-out-event",
549 G_CALLBACK(gmail_config_username_focus_out_cb), gmailbox);
550 gtk_label_set_mnemonic_widget(GTK_LABEL(lbl), entry);
551
552 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BORDER/2);
553 gtk_widget_show(hbox);
554 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
555
556 lbl = gtk_label_new_with_mnemonic(_("_Password:"));
557 gtk_label_set_xalign(GTK_LABEL(lbl), 0.0);
558 gtk_widget_show(lbl);
559 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 0);
560 gtk_size_group_add_widget(sg, lbl);
561
562 entry = gtk_entry_new();
563 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
564 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
565 if(gmailbox->password)
566 gtk_entry_set_text(GTK_ENTRY(entry), gmailbox->password);
567 gtk_widget_show(entry);
568 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
569 g_signal_connect(G_OBJECT(entry), "focus-out-event",
570 G_CALLBACK(gmail_config_password_focus_out_cb), gmailbox);
571 gtk_label_set_mnemonic_widget(GTK_LABEL(lbl), entry);
572
573 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BORDER/2);
574 gtk_widget_show(hbox);
575 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
576
577 lbl = gtk_label_new_with_mnemonic(_("Check for _new messages every"));
578 gtk_widget_show(lbl);
579 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 0);
580
581 sbtn = gtk_spin_button_new_with_range(1.0, 1440.0, 1.0);
582 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(sbtn), TRUE);
583 gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(sbtn), FALSE);
584 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sbtn), gmailbox->timeout/60);
585 gtk_widget_show(sbtn);
586 gtk_box_pack_start(GTK_BOX(hbox), sbtn, FALSE, FALSE, 0);
587 g_signal_connect(G_OBJECT(sbtn), "value-changed",
588 G_CALLBACK(gmail_config_timeout_spinbutton_changed_cb),
589 gmailbox);
590 gtk_label_set_mnemonic_widget(GTK_LABEL(lbl), sbtn);
591
592 lbl = gtk_label_new(_("minute(s)."));
593 gtk_widget_show(lbl);
594 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 0);
595
596 return GTK_CONTAINER(vbox);
597 }
598
599 static void
gmail_restore_param_list(XfceMailwatchMailbox * mailbox,GList * params)600 gmail_restore_param_list(XfceMailwatchMailbox *mailbox, GList *params)
601 {
602 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(mailbox);
603 GList *l;
604
605 g_mutex_lock(&(gmailbox->config_mx));
606
607 for(l = params; l; l = l->next) {
608 XfceMailwatchParam *param = l->data;
609
610 if(!strcmp(param->key, "username"))
611 gmailbox->username = g_strdup(param->value);
612 else if(!strcmp(param->key, "password"))
613 gmailbox->password = g_strdup(param->value);
614 else if(!strcmp(param->key, "timeout"))
615 gmailbox->timeout = atoi(param->value);
616 }
617
618 g_mutex_unlock(&(gmailbox->config_mx));
619 }
620
621 static GList *
gmail_save_param_list(XfceMailwatchMailbox * mailbox)622 gmail_save_param_list(XfceMailwatchMailbox *mailbox)
623 {
624 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(mailbox);
625 GList *params = NULL;
626 XfceMailwatchParam *param;
627
628 g_mutex_lock(&(gmailbox->config_mx));
629
630 param = g_new(XfceMailwatchParam, 1);
631 param->key = g_strdup("username");
632 param->value = g_strdup(gmailbox->username);
633 params = g_list_prepend(params, param);
634
635 param = g_new(XfceMailwatchParam, 1);
636 param->key = g_strdup("password");
637 param->value = g_strdup(gmailbox->password);
638 params = g_list_prepend(params, param);
639
640 param = g_new(XfceMailwatchParam, 1);
641 param->key = g_strdup("timeout");
642 param->value = g_strdup_printf("%u", gmailbox->timeout);
643 params = g_list_prepend(params, param);
644
645 g_mutex_unlock(&(gmailbox->config_mx));
646
647 return g_list_reverse(params);
648 }
649
650 static void
gmail_mailbox_free(XfceMailwatchMailbox * mailbox)651 gmail_mailbox_free(XfceMailwatchMailbox *mailbox)
652 {
653 XfceMailwatchGMailMailbox *gmailbox = XFCE_MAILWATCH_GMAIL_MAILBOX(mailbox);
654
655 gmail_set_activated(mailbox, FALSE);
656 while(g_atomic_pointer_get(&gmailbox->th))
657 g_thread_yield();
658
659 g_mutex_clear(&gmailbox->config_mx);
660
661 g_free(gmailbox->username);
662 g_free(gmailbox->password);
663
664 g_free(gmailbox);
665 }
666
667 XfceMailwatchMailboxType builtin_mailbox_type_gmail = {
668 "gmail",
669 N_("Remote GMail Mailbox"),
670 N_("The GMail plugin can connect to Google's mail service and securely retrieve the number of new messages."),
671
672 gmail_mailbox_new,
673 gmail_set_activated,
674 gmail_force_update_cb,
675 gmail_get_setup_page,
676 gmail_restore_param_list,
677 gmail_save_param_list,
678 gmail_mailbox_free
679 };
680