Beispiel #1
0
gint timeout_command (gpointer data)
{
  datastruct * ds = (datastruct * )data;
  char * strbuf=NULL;
  int time_current=time_max-(time(NULL)-start_time);

  gtk_progress_configure(GTK_PROGRESS(ds->progress),
			 (float)time_current / (float)time_max * 100.0,
			 0.0, 100);
  asprintf (&strbuf, "%i:%.2i",
	    time_current / 60,
	    time_current % 60);

  gtk_label_set_text (GTK_LABEL(ds->text), strbuf);
  free (strbuf);

  if (time_current < timeout[current_timeout].threshold)
    {
      system(timeout[current_timeout].command);
      current_timeout++;
      if (!timeout[current_timeout].command)
	exit (1);
    }

  return 1;
}
Beispiel #2
0
/* Allows the configuration of the minimum, maximum,
 * and current values for the GtkProgress. */
int
clip_GTK_PROGRESSCONFIGURE(ClipMachine * cm)
{
	C_widget *cprg = _fetch_cw_arg(cm);
	gfloat   value = _clip_parnd(cm,2);
	gfloat     min = _clip_parnd(cm,3);
	gfloat     max = _clip_parnd(cm,4);
        CHECKCWID(cprg,GTK_IS_PROGRESS);
	CHECKOPT(2,NUMERIC_t); CHECKOPT(3,NUMERIC_t); CHECKOPT(4,NUMERIC_t);
        gtk_progress_configure(GTK_PROGRESS(cprg->widget),value,min,max);
	return 0;
err:
	return 1;
}
Beispiel #3
0
static GtkWidget *
progressbar_new(GladeXML *xml, GladeWidgetInfo *info)
{
	GtkWidget *ret = gtk_progress_bar_new();
	GList *tmp;
	gfloat value = 0, lower = 0, upper = 100;
	gfloat xalign = 0.5, yalign = 0.5;

	for (tmp = info->attributes; tmp; tmp = tmp->next) {
		GladeAttribute *attr = tmp->data;

		if (!strcmp(attr->name, "value"))
			value = g_strtod(attr->value, NULL);
		else if (!strcmp(attr->name, "lower"))
			lower = g_strtod(attr->value, NULL);
		else if (!strcmp(attr->name, "upper"))
			upper = g_strtod(attr->value, NULL);
		else if (!strcmp(attr->name, "activity_mode"))
			gtk_progress_set_activity_mode(GTK_PROGRESS(ret),
						       attr->value[0]=='T');
		else if (!strcmp(attr->name, "bar_style"))
			gtk_progress_bar_set_bar_style(GTK_PROGRESS_BAR(ret),
			    glade_enum_from_string(GTK_TYPE_PROGRESS_BAR_STYLE,
						   attr->value));
		else if (!strcmp(attr->name, "orientation"))
			gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(ret),
			    glade_enum_from_string(
			      GTK_TYPE_PROGRESS_BAR_ORIENTATION, attr->value));
		else if (!strcmp(attr->name, "show_text"))
			gtk_progress_set_show_text(GTK_PROGRESS(ret),
						   attr->value[0] == 'T');
		else if (!strcmp(attr->name, "text_xalign"))
			xalign = g_strtod(attr->value, NULL);
		else if (!strcmp(attr->name, "text_yalign"))
			yalign = g_strtod(attr->value, NULL);
		else if (!strcmp(attr->name, "format"))
			gtk_progress_set_format_string(GTK_PROGRESS(ret),
						       attr->value);
	}
	gtk_progress_configure(GTK_PROGRESS(ret), value, lower, upper);
	gtk_progress_set_text_alignment(GTK_PROGRESS(ret), xalign, yalign);
	return ret;
}
Beispiel #4
0
void *
check_pop_main (Account *account) {
  char *buf = NULL, *buf2, *buf3;
  C2ResolveNode *resolve;
  int sock;
  int timedout = FALSE;
  struct sockaddr_in server;
  
  int messages = 0, bytes = 0, downloaded_bytes = 0, i = 0, password_errors = 3;
  
  GList *download[DOWNLOAD_LIST_LAST], *uidl_search = NULL, *top_search = NULL;
  GList *list;
  gboolean supports_uidl = FALSE;
  
  mid_t mid;
  
  FILE *index;
  FILE *mail;

  Message message;
  char *mailbox;
  Mailbox *mbox;
  GString *strmsg;
  char *header[HEADER_LAST];
  gboolean reading_header = TRUE;
  gboolean with_attachs = FALSE;
  char *content_type;

  char *row[8];
  GtkStyle *style, *style2;
  gboolean clisted = FALSE;
  
  g_return_val_if_fail (account, NULL);
  g_return_val_if_fail (account->type == C2_ACCOUNT_POP, NULL);

  download[DOWNLOAD_LIST_TOTAL] = NULL;
  download[DOWNLOAD_LIST_UIDL] = NULL;
  download[DOWNLOAD_LIST_TOP] = NULL;  

  resolve = c2_resolve (account->protocol.pop.host, &buf);
  if (buf) {
    gdk_threads_enter ();
    window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
    gdk_threads_leave ();
    return NULL;
  }

  sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sock < 0) {
    gdk_threads_enter ();
    window_checking_report (C2_CHECK_ERR, account->acc_name, _("Failed to create socket"));
    gdk_threads_leave ();
    return NULL;
  }

  server.sin_family	= AF_INET;
  server.sin_port	= htons (account->protocol.pop.host_port);
  server.sin_addr.s_addr= inet_addr (resolve->ip);

  if (connect (sock, (struct sockaddr *)&server, sizeof (server)) < 0) {
    buf = g_strerror (errno);
    gdk_threads_enter ();
    window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
    gdk_threads_leave ();
    return NULL;
  }

  /* Guten Morgen, Herr Server! */
  buf = sock_read (sock, &timedout);
  if (pop_check_answer (buf, account, timedout) < 0) {
    if (timedout) goto run_for_your_life;
    goto bye_bye_server;
  }
  c2_free (buf);

  /* Log In */
  gdk_threads_enter ();
  gtk_progress_set_format_string (GTK_PROGRESS (window_checking->mail_progress),
     		_("Logging in..."));
  gdk_threads_leave ();

retry_login:
  if (sock_printf (sock, "USER %s\r\n", account->protocol.pop.usr_name) < 0) {
    buf = g_strerror (errno);
    gdk_threads_enter ();
    window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
    gdk_threads_leave ();
    goto bye_bye_server;
  }

  buf = sock_read (sock, &timedout);
  if (pop_check_answer (buf, account, timedout) < 0) {
    if (timedout) goto run_for_your_life;
    goto bye_bye_server;
  }
  c2_free (buf);

  if (sock_printf (sock, "PASS %s\r\n", account->protocol.pop.pass) < 0) {
    buf = g_strerror (errno);
    gdk_threads_enter ();
    window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
    gdk_threads_leave ();
    goto bye_bye_server;
  }

  buf = sock_read (sock, &timedout);
  if (strnne (buf, "+OK", 3)) {
    if (--password_errors < 0) {
      if (pop_check_answer (buf, account, timedout) < 0) {
	if (timedout) goto run_for_your_life;
	goto bye_bye_server;
      }
    }
    gdk_threads_enter ();
    if (!gui_ask_password (account)) {
      gdk_threads_leave ();
      if (pop_check_answer (buf, account, timedout) < 0) {
	if (timedout) goto run_for_your_life;
	goto bye_bye_server;
      }
    } else {
      gdk_threads_leave ();
      goto retry_login;
    }
  }
  c2_free (buf);

  /* STAT */
  gdk_threads_enter ();
  gtk_progress_set_format_string (GTK_PROGRESS (window_checking->mail_progress),
      		_("Checking for number of mails in server..."));
  gdk_threads_leave ();

  if (sock_printf (sock, "STAT\r\n") < 0) {
    buf = g_strerror (errno);
    gdk_threads_enter ();
    window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
    gdk_threads_leave ();
    goto bye_bye_server;
  }

  buf = sock_read (sock, &timedout);
  if (pop_check_answer (buf, account, timedout) < 0) {
    if (timedout) goto run_for_your_life;
    goto bye_bye_server;
  }
  sscanf (buf, "+OK %d ", &messages);
  c2_free (buf);
 
  if (!messages) {
    gdk_threads_enter ();
    gtk_progress_set_format_string (GTK_PROGRESS (window_checking->mail_progress),
      		_("No messages in server"));
    window_checking_report (C2_CHECK_OK, account->acc_name, _("No messages to download"));
    gdk_threads_leave ();
    clisted = TRUE;
    goto bye_bye_server;
  }
  else if (messages != 1)
    buf = g_strdup_printf (_("%d messages in server"), messages);
  else
    buf = g_strdup_printf (_("1 message in server"));
  gdk_threads_enter ();
  gtk_progress_set_format_string (GTK_PROGRESS (window_checking->mail_progress),
      		buf);
  gdk_threads_leave ();
  c2_free (buf);

  /* UIDL */
  if (!account->keep_copy) {
dont_use_uidl:
    /* Without UIDL*/
    for (i = 1; i <= messages; i++) {
      buf = g_strdup_printf ("%d", i);
      download[DOWNLOAD_LIST_UIDL] = g_list_append (download[DOWNLOAD_LIST_UIDL], (gpointer) buf);
    }
  } else {
    /* With UIDL */
    if (sock_printf (sock, "UIDL\r\n") < 0) {
      buf = g_strerror (errno);
      gdk_threads_enter ();
      window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
      gdk_threads_leave ();
      goto bye_bye_server;
    }
    
    for (i = 0;; i++) {
      buf = sock_read (sock, &timedout);
      if (!i && strnne (buf, "+OK", 3)) {
	/* UIDL is optional for POP servers,
	 * so I won't complain if server doesn't like it */
	buf2 = g_strdup_printf (_("The POP server of the account %s doesn't support UIDL."),
	    	account->acc_name);
	gdk_threads_enter ();
	gnome_appbar_set_status (GNOME_APPBAR (WMain->appbar), buf2);
	gdk_threads_leave ();
	supports_uidl = FALSE;
	goto dont_use_uidl;
      }
      supports_uidl = TRUE;
      if (!i) continue;
      if (streq (buf, ".\r\n")) break;

      buf2 = str_get_word (1, buf, ' ');
      buf3 = str_strip (buf2, '\r');
      buf2 = str_strip (buf3, '\n');
      if (!uidl_check (buf2, account->acc_name)) {
	download[DOWNLOAD_LIST_UIDL] = g_list_append (download[DOWNLOAD_LIST_UIDL], buf);
      }
    }
  }
 
  /* TOP */
  if (!config->message_bigger) {
    /* Without TOP */
dont_use_list:
dont_use_top:
    for (i = 1; i <= messages; i++)
      	download[DOWNLOAD_LIST_TOP] = g_list_append (download[DOWNLOAD_LIST_TOP], (gpointer) i);
  } else {
    /* With TOP */
    char *subject, *from, *date, *kbytes;
    
    if (sock_printf (sock, "LIST\r\n") < 0) {
      buf = g_strerror (errno);
      gdk_threads_enter ();
      window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
      gdk_threads_leave ();
      goto bye_bye_server;
    }
    
    for (i = 0;; i++) {
      buf = sock_read (sock, &timedout);
      if (!i && strnne (buf, "+OK", 3)) {
	buf2 = g_strdup_printf (_("The POP server of the account %s doesn't support LIST."),
	    	account->acc_name);
	gdk_threads_enter ();
	gnome_appbar_set_status (GNOME_APPBAR (WMain->appbar), buf2);
	gdk_threads_leave ();
	goto dont_use_list;
      }
      if (!i) continue;
      if (streq (buf, ".\r\n")) break;
      buf2 = str_get_word (1, buf, ' ');
      str_strip (buf2, '\r');
      str_strip (buf2, '\n');
      download[DOWNLOAD_LIST_TOP] = g_list_append (download[DOWNLOAD_LIST_TOP], buf);
      c2_free (buf2);
    }

    for (list = download[DOWNLOAD_LIST_TOP]; list; list = list->next) {
      if (sock_printf (sock, "TOP %d 0\r\n", atoi (CHAR (list->data))) < 0) {
	buf = g_strerror (errno);
	gdk_threads_enter ();
	window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
	gdk_threads_leave ();
	goto bye_bye_server;
      }

      strmsg = g_string_new (NULL);
      for (i = 0;; i++) {
	buf = sock_read (sock, &timedout);
	if (!i && strnne (buf, "+OK", 3)) {
	  buf2 = g_strdup_printf (_("The POP server of the account %s doesn't support TOP."),
	      account->acc_name);
	  gdk_threads_enter ();
	  gnome_appbar_set_status (GNOME_APPBAR (WMain->appbar), buf2);
	  gdk_threads_leave ();
	  goto dont_use_top;
	}
	if (!i) continue;
	if (streq (buf, ".\r\n")) break;
	g_string_append (strmsg, buf);
	c2_free (buf);
      }
      subject = message_get_header_field (NULL, strmsg->str, "\nSubject:");
      from = message_get_header_field (NULL, strmsg->str, "From:");
      date = message_get_header_field (NULL, strmsg->str, "\nDate:");
      kbytes = str_get_word (1, CHAR (list->data), ' '); str_strip (kbytes, '\r');str_strip (kbytes, '\n');
      gdk_threads_enter ();
      if ((atoi (kbytes) >= config->message_bigger*1024) &&
	  (!gui_message_big_new (from, subject, date, account->acc_name, kbytes))) {
	gdk_threads_leave ();
	c2_free (list->data);
	list->data = NULL;
	download[DOWNLOAD_LIST_TOP] = g_list_remove_link (download[DOWNLOAD_LIST_TOP], list);
      } else gdk_threads_leave ();
    }
  }

  /* Learn messages to download */
  if (!account->keep_copy && !config->message_bigger) {		/* !UIDL AND !TOP */
    download[DOWNLOAD_LIST_TOTAL] = download[DOWNLOAD_LIST_UIDL];
  }
  else if (account->keep_copy && !config->message_bigger) {	/*  UIDL AND !TOP */
    for (list = download[DOWNLOAD_LIST_UIDL]; list; list = list->next) {
      download[DOWNLOAD_LIST_TOTAL] = g_list_append (download[DOWNLOAD_LIST_TOTAL], 
	 					str_get_word (0, CHAR (list->data), ' '));
    }
  }
  else if (!account->keep_copy && config->message_bigger) {	/* !UIDL AND  TOP */
    download[DOWNLOAD_LIST_TOTAL] = download[DOWNLOAD_LIST_TOP];
  }
  else if (account->keep_copy && config->message_bigger) {	/*  UIDL AND  TOP */
    for (uidl_search = download[DOWNLOAD_LIST_UIDL]; !uidl_search; uidl_search = uidl_search->next) {
      for (top_search = download[DOWNLOAD_LIST_TOP]; !top_search; top_search = top_search->next) {
	printf ("%d %d\n", (int) uidl_search->data, (int) top_search->data); /* TODO */
      }
    }
  }

  messages = g_list_length (download[DOWNLOAD_LIST_TOTAL]);
  gdk_threads_enter ();
  gtk_progress_configure (GTK_PROGRESS (window_checking->mail_progress), 0, 0, messages);
  gtk_progress_set_format_string (GTK_PROGRESS (window_checking->mail_progress),
      				_("%p%% downloaded (%v of %u messages)"));
  gdk_threads_leave ();

  strmsg = g_string_new (NULL);
  message.message = message.header = NULL;
  for (list = download[DOWNLOAD_LIST_TOTAL]; list; list = list->next) {
    buf = str_get_word (0, CHAR (list->data), ' ');
    i = atoi (buf);
    c2_free (buf);
    /* Ask for the mail */
    if (sock_printf (sock, "RETR %d\r\n", i) < 0) {
      buf = g_strerror (errno);
      gdk_threads_enter ();
      window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
      gdk_threads_leave ();
      goto bye_bye_server;
    }

    /* Read the first line */
    buf = sock_read (sock, &timedout);
    if (pop_check_answer (buf, account, timedout) < 0) {
      if (timedout) goto run_for_your_life;
      goto bye_bye_server;
    }
    /* Learn bytes in the messages */
    sscanf (buf, "+OK %d octets\r\n", &bytes);
    if (bytes) {
      gdk_threads_enter ();
      gtk_progress_configure (GTK_PROGRESS (window_checking->bytes_progress), 0, 0, bytes);
      gtk_widget_show (window_checking->bytes_progress);
      gdk_threads_leave ();
    } else {
      gdk_threads_enter ();
      gtk_widget_hide (window_checking->bytes_progress);
      gdk_threads_leave ();
    }
    c2_free (buf);
    
    /* Get the mail */
    reading_header = TRUE;
    for (;;) {
      buf = sock_read (sock, &timedout);
      if (bytes) {
	downloaded_bytes += strlen (buf);
	gdk_threads_enter ();
	gtk_progress_set_value (GTK_PROGRESS (window_checking->bytes_progress), downloaded_bytes);
	gdk_threads_leave ();
      }
      if (streq (buf, ".\r\n")) {
	message.message = g_strdup (strmsg->str);
	g_string_assign (strmsg, "");
	str_strip (message.message, '\r');
	break;
      }
      if (reading_header && strlen (buf) > 2) {
	char *buf2;
	buf2 = decode_8bit (buf);
	c2_free (buf);
	buf = buf2;
      }
      if (reading_header && strlen (buf) == 2) { /* Still reading header and is an empty line */
	buf2 = g_strdup_printf ("X-CronosII-Account: %s\r\n", account->acc_name);
	g_string_append (strmsg, buf2);
	c2_free (buf2);
	reading_header = FALSE;
      }
      g_string_append (strmsg, buf);
    }
    gtk_progress_set_percentage (GTK_PROGRESS (window_checking->bytes_progress), 1);

    /* Write to the mail file */
    mailbox = account->mailbox->name;
#if USE_PLUGINS
    c2_dynamic_module_signal_emit (C2_DYNAMIC_MODULE_MESSAGE_DOWNLOAD_POP, &message,
      				 	&mailbox, NULL, NULL, NULL);
#endif
    mbox = search_mailbox_name (config->mailbox_head, mailbox);
    if (!mbox) {
      /* Mailbox couldn't be found, going with the default */
      mbox = account->mailbox;
    }
    mid = c2_mailbox_get_next_mid (mbox);
    buf = c2_mailbox_mail_path (mailbox, mid);
    if ((mail = fopen (buf, "w")) == NULL) {
      gdk_threads_enter ();
      window_checking_report (C2_CHECK_ERR, account->acc_name,
	  _("Error opening the file where to store the new mail"));
      cronos_error (errno, _("Opening the mail file"), ERROR_WARNING);
      gdk_threads_leave ();
      c2_free (buf);
      continue;
    }
    c2_free (buf);
    fprintf (mail, "%s", message.message);
    fclose (mail);

    /* Write to the index file */
    buf = c2_mailbox_index_path (mailbox);
    if ((index = fopen (buf, "a")) == NULL) {
      gdk_threads_enter ();
      window_checking_report (C2_CHECK_ERR, account->acc_name,
	  _("Error opening the main DB file to store the new mail"));
      cronos_error (errno, _("Opening the main DB file"), ERROR_WARNING);
      gdk_threads_leave ();
      c2_free (buf);
      goto bye_bye_server;
    }
    header[HEADER_SUBJECT]	= message_get_header_field (&message, NULL, "\nSubject:");
    header[HEADER_FROM]		= message_get_header_field (&message, NULL, "\nFrom:");
    header[HEADER_DATE]		= message_get_header_field (&message, NULL, "\nDate:");
    content_type		= message_get_header_field (&message, NULL, "\nContent-Type:");
    with_attachs		= FALSE;
/*    if (content_type) {
      message_mime_parse_content_type (content_type, &type, &subtype, &parameter);
      if (streq (type, "multipart")) {
	GList *s;
	MimeHash *mime;
	message_mime_parse (&message, NULL);
	for (s = message.mime; s != NULL; s = s->next) {
	  mime = MIMEHASH (s->data);
	  if (!mime) continue;
	  if (strneq (mime->disposition, "attachment", 10)) with_attachs = TRUE;
	}
      }
    }*/

    if (!header[HEADER_SUBJECT]) header[HEADER_SUBJECT] = "";
    if (!header[HEADER_FROM]) header[HEADER_FROM] = "";
    if (!header[HEADER_DATE]) header[HEADER_DATE] = "";
    fprintf (index, "N\r\r%s\r%s\r%s\r%s\r%s\r%d\n",
		with_attachs ? "1" : "", header[HEADER_SUBJECT], header[HEADER_FROM], header[HEADER_DATE],
		account->acc_name, mid);
    fclose (index);
    c2_free (message.message);
    c2_free (message.header);
    message.message = message.header = NULL;

    if (!account->keep_copy) {
      /* Delete the message */
      if (sock_printf (sock, "DELE %d\r\n", i) < 0) {
	buf = g_strerror (errno);
	gdk_threads_enter ();
	window_checking_report (C2_CHECK_ERR, account->acc_name, buf);
	gdk_threads_leave ();
	goto bye_bye_server;
      }
      buf = sock_read (sock, &timedout);
      if (pop_check_answer (buf, account, timedout) < 0) {
	if (timedout) goto run_for_your_life;
	goto bye_bye_server;
      }
    }
    
    if (streq (selected_mbox, mailbox)) {
      row[0] = "";
      row[1] = "";
      row[2] = "";
      row[3] = header[HEADER_SUBJECT];
      row[4] = header[HEADER_FROM];
      row[5] = header[HEADER_DATE];
      row[6] = account->acc_name;
      row[7] = g_strdup_printf ("%d", mid);
      
      gdk_threads_enter ();
      gtk_clist_freeze (GTK_CLIST (WMain->clist));
      gtk_clist_append (GTK_CLIST (WMain->clist), row);
      style = gtk_widget_get_style (WMain->clist);
      style2 = gtk_style_copy (style);
      style2->font = font_unread;
      gtk_clist_set_row_style (GTK_CLIST (WMain->clist), GTK_CLIST (WMain->clist)->rows-1, style2);
      gtk_clist_set_pixmap (GTK_CLIST (WMain->clist), GTK_CLIST (WMain->clist)->rows-1, 0, pixmap_unread, mask_unread);
      if (with_attachs) gtk_clist_set_pixmap (GTK_CLIST (WMain->clist), GTK_CLIST (WMain->clist)->rows-1, 2, pixmap_attach, mask_attach);
      new_messages++;
      gtk_clist_thaw (GTK_CLIST (WMain->clist));
      gtk_clist_set_row_data (GTK_CLIST (WMain->clist), GTK_CLIST (WMain->clist)->rows-1, (gpointer) "N");
      update_wm_title ();
      gtk_progress_set_value (GTK_PROGRESS (window_checking->mail_progress), i);
      gdk_threads_leave ();
      clisted = TRUE;
    }
    gdk_threads_enter ();
    gtk_progress_set_value (GTK_PROGRESS (window_checking->mail_progress),
		gtk_progress_get_value (GTK_PROGRESS (window_checking->mail_progress))+1);
    gdk_threads_leave ();
  }
  if (supports_uidl) {
    GList *llist;
    for (llist = download[DOWNLOAD_LIST_UIDL]; llist != NULL; llist = llist->next) {
      char *uidl;
      uidl = CHAR (llist->data);
      buf2 = str_get_word (1, uidl, ' ');
      buf3 = str_strip (buf2, '\r');
      buf2 = str_strip (buf3, '\n');
      if (buf2) {
	uidl_register (buf2, account->acc_name);
      }
    }
  }
        
  if (messages != 1)
    buf = g_strdup_printf (_("%d messages downloaded."), messages);
  else
    buf = g_strdup_printf (_("1 message downloaded."));
  gdk_threads_enter ();
  gtk_progress_configure (GTK_PROGRESS (window_checking->mail_progress), messages, 0, messages);
  gtk_progress_set_format_string (GTK_PROGRESS (window_checking->mail_progress),
      				buf);
  window_checking_report (C2_CHECK_OK, account->acc_name, buf);
  gdk_threads_leave ();
  
bye_bye_server:
  if (sock_printf (sock, "QUIT\r\n") < 0) {
    buf = g_strerror (errno);
  }
  
  buf = sock_read (sock, &timedout);
  if (pop_check_answer (buf, account, timedout) < 0) {
    if (timedout) goto run_for_your_life;
  }
run_for_your_life:
  close (sock);
  return NULL;
}
GtkWindow * gw_progress_bar_box_create ( GtkWindow *window, gchar *title, gchar *subject, gchar *text, gfloat max, func_stop_progress_t stop, gpointer p)
{
	GtkWidget *w = NULL;
	GtkWidget *frame;
	GtkWidget *vbox;
	GtkWidget *hbox;
	GtkWidget *file_name;
	GtkWidget *progress_bar	= NULL;
	GtkWidget *button;
	guint button_key;
	GtkAccelGroup *accel = NULL;
	gchar *text_utf8 = NULL;


#ifdef GW_DEBUG_GUI_COMPONENT
	g_print	( "*** GW - %s (%d) :: %s() : %f\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, max);
#endif

	/* Inits accel group for keystroke shortcuts */
	accel =	gtk_accel_group_new ( );

	if ( !w	)
	{
		w = gtk_window_new ( GTK_WINDOW_DIALOG);
		gtk_window_set_policy (	GTK_WINDOW ( w), FALSE,	FALSE, FALSE);
		g_strdup_to_gtk_text ( title, text_utf8);
		gtk_window_set_title ( GTK_WINDOW ( w),	text_utf8);
		g_free ( text_utf8);
		gtk_container_border_width ( GTK_CONTAINER ( w), 5);

		gtk_window_set_modal ( GTK_WINDOW ( w),TRUE);
		gtk_window_set_transient_for ( GTK_WINDOW ( w),	window);
		gtk_window_set_position	( GTK_WINDOW ( w), GTK_WIN_POS_CENTER);

		gtk_widget_ref ( GTK_WIDGET ( window));
		gtk_object_set_data_full ( GTK_OBJECT (	w), GW_REF_PROGRESS_BAR_BOX_PARENT_WINDOW, window, (GtkDestroyNotify) gtk_widget_unref);

		if ( stop != NULL )
		{
#ifdef GW_DEBUG_GUI_COMPONENT
			g_print	( "*** GW - %s (%d) :: %s() : connect signals on delete_event and destroy\n", __FILE__,	__LINE__, __PRETTY_FUNCTION__);
#endif

			/* These signals do nothing. In	this way the window cannot be destroyed. What must be done when	stop is	NULL? */
			gtk_signal_connect ( GTK_OBJECT	( w), "delete_event", GTK_SIGNAL_FUNC (	gw_progress_bar_box_signal_do_nothing), NULL);
			gtk_signal_connect ( GTK_OBJECT	( w), "destroy", GTK_SIGNAL_FUNC ( gw_progress_bar_box_signal_do_nothing),	NULL);
		}

		g_strdup_to_gtk_text ( subject, text_utf8);
		frame =	gtk_frame_new (	text_utf8);
		g_free ( text_utf8);
		gtk_container_add ( GTK_CONTAINER ( w),	frame);

		vbox = gtk_vbox_new ( FALSE, 0);
		gtk_container_add ( GTK_CONTAINER ( frame), vbox);
		gtk_container_set_border_width ( GTK_CONTAINER ( vbox),	10);

		g_strdup_to_gtk_text ( text, text_utf8);
		file_name = gtk_label_new ( text_utf8);
		g_free ( text_utf8);

		/* Store the reference to the text info	label to describe the current processing. */
		gtk_widget_ref ( file_name);
		gtk_object_set_data_full ( GTK_OBJECT (	w), GW_REF_PROGRESS_BAR_BOX_TEXT_INFO_LABEL, file_name,	(GtkDestroyNotify) gtk_widget_unref);
		gtk_label_set_justify (	GTK_LABEL ( file_name),	GTK_JUSTIFY_LEFT);
		gtk_box_pack_start ( GTK_BOX ( vbox), file_name, TRUE, TRUE, 0);

#ifdef GW_DEBUG_GUI_COMPONENT
		g_print	( "*** GW - %s (%d) :: %s() : creates the real progress	bar\n",	__FILE__, __LINE__, __PRETTY_FUNCTION__);
#endif
		progress_bar = gtk_progress_bar_new ( );

		/* Store reference to the real progress	bar */
		gtk_widget_ref ( progress_bar);
		gtk_object_set_data_full ( GTK_OBJECT (	w), GW_REF_PROGRESS_BAR_BOX_PROGRESS_BAR, progress_bar,	(GtkDestroyNotify) gtk_widget_unref);

		/* Doesn't show	the progress bar if max	value is 0 */
		if ( max > 0 )
		{
			gtk_progress_configure ( GTK_PROGRESS (	progress_bar), 0, 0, max);
			gtk_progress_set_show_text ( GTK_PROGRESS ( progress_bar), TRUE);

			/* Set the format string of progess state visualization	*/
			g_strdup_to_gtk_text ( GW_PROGRESS_BAR_BOX_PROGRESS_BAR_FORMAT_STRING, text_utf8);
			gtk_progress_set_format_string ( GTK_PROGRESS (	progress_bar), text_utf8);
			g_free ( text_utf8);
			gtk_box_pack_start ( GTK_BOX ( vbox), progress_bar, TRUE, TRUE,	0);
		}

		hbox = gtk_hbox_new ( TRUE, 10);
		gtk_container_add ( GTK_CONTAINER ( vbox), hbox);
		gtk_container_set_border_width ( GTK_CONTAINER ( hbox),	5);

		button = gtk_button_new_with_label ( "");

		/* Store reference to the ok/cancel button */
		gtk_widget_ref ( button);
		gtk_object_set_data_full ( GTK_OBJECT (	w), GW_REF_PROGRESS_BAR_BOX_OK_CANCEL_BUTTON, button, (GtkDestroyNotify) gtk_widget_unref);
		gw_progress_bar_box_set_state ( GTK_WINDOW ( w), STATE_CANCEL);
		g_strdup_to_gtk_text ( _( "_Cancel"), text_utf8);
		button_key = gtk_label_parse_uline ( GTK_LABEL ( GTK_BIN ( button)->child), text_utf8);
		g_free ( text_utf8);
		gtk_widget_add_accelerator ( button, "clicked",	accel, button_key, GDK_MOD1_MASK, 0);
		gtk_object_set_user_data ( GTK_OBJECT (	button), w);
		gtk_box_pack_start ( GTK_BOX ( hbox), button, TRUE, TRUE, 0);
		gtk_widget_grab_focus ( button);

		if ( stop != NULL )
		{
#ifdef GW_DEBUG_GUI_COMPONENT
			g_print	( "*** GW - %s (%d) :: %s() : connect custom callback on ok/cancel button\n", __FILE__,	__LINE__, __PRETTY_FUNCTION__);
#endif

			gtk_signal_connect ( GTK_OBJECT	( button), "clicked", GTK_SIGNAL_FUNC (	stop), p);
		}
		else
		{
#ifdef GW_DEBUG_GUI_COMPONENT
			g_print	( "*** GW - %s (%d) :: %s() : connect standard callback	on ok/cancel button\n",	__FILE__, __LINE__, __PRETTY_FUNCTION__);
#endif

			gtk_signal_connect ( GTK_OBJECT	( button), "clicked", GTK_SIGNAL_FUNC (	gw_progress_bar_box_ok_cancel_click), w);
		}

		gtk_window_add_accel_group ( GTK_WINDOW	( w), accel);
	}

	if ( !GTK_WIDGET_VISIBLE ( w) )
	{
#ifdef GW_DEBUG_GUI_COMPONENT
			g_print	( "*** GW - %s (%d) :: %s() : show window\n", __FILE__,	__LINE__, __PRETTY_FUNCTION__);
#endif

		gtk_widget_show_all ( w);
	}
	else
	{
#ifdef GW_DEBUG_GUI_COMPONENT
			g_print	( "*** GW - %s (%d) :: %s() : destroy window\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
#endif

		gtk_widget_destroy ( w);
	}

	return GTK_WINDOW ( w);
}