mailcheck applet support for tunnels



Hi!

I have created a patch against gnome-applets 2.4.2-6 (debian version) which
adds support for tunnels to mailcheck. There is a new option under the
preferences for "Commands, Establish connection:". The patch also allows
mailcheck to recognize preauthenticated IMAP sessions and not login in this
case (which would fail).

This allows for use of ssh powered tunnels to an IMAP server.
Please consider applying it.

-- 
Wesley W. Terpstra
diff -cr gnome-applets-2.4.2.orig/mailcheck/mailcheck.c gnome-applets-2.4.2/mailcheck/mailcheck.c
*** gnome-applets-2.4.2.orig/mailcheck/mailcheck.c	Mon Sep 15 23:24:58 2003
--- gnome-applets-2.4.2/mailcheck/mailcheck.c	Wed Apr 21 17:38:39 2004
***************
*** 91,97 ****
  
  	/* execute a command before checking email (fetchmail etc.) */
  	char *pre_check_cmd;
! 	gboolean pre_check_enabled;	
  
  	PanelApplet *applet;
  	/* This is the event box for catching events */
--- 91,101 ----
  
  	/* execute a command before checking email (fetchmail etc.) */
  	char *pre_check_cmd;
! 	gboolean pre_check_enabled;
! 	
! 	/* execute a command to establish connection (ssh tunnel etc.) */
! 	char *connection_cmd;
! 	gboolean connection_enabled;	
  
  	PanelApplet *applet;
  	/* This is the event box for catching events */
***************
*** 137,142 ****
--- 141,147 ----
  	GtkWidget *property_window;
  	GtkWidget *min_spin, *sec_spin;
  	GtkWidget *pre_check_cmd_entry, *pre_check_cmd_check;
+ 	GtkWidget *connection_cmd_entry, *connection_cmd_check;
  	GtkWidget *newmail_cmd_entry, *newmail_cmd_check;
  	GtkWidget *clicked_cmd_entry, *clicked_cmd_check;
  
***************
*** 727,733 ****
  static void
  check_remote_mailbox (MailCheck *mc)
  {
! 	if (!mc->real_password || !mc->remote_username || !mc->remote_server)
  		return;
  
  	if (mc->mailbox_type == MAILBOX_POP3)
--- 732,739 ----
  static void
  check_remote_mailbox (MailCheck *mc)
  {
! 	if ((!mc->real_password || !mc->remote_username || !mc->remote_server)
! 	    && !mc->connection_cmd)
  		return;
  
  	if (mc->mailbox_type == MAILBOX_POP3)
***************
*** 736,741 ****
--- 742,748 ----
  						       mc,
  						       null_remote_handle,
  						       NULL,
+ 						       mc->connection_cmd,
  						       mc->remote_server,
  						       mc->remote_username,
  						       mc->real_password);
***************
*** 745,750 ****
--- 752,758 ----
  						       mc,
  						       null_remote_handle,
  						       NULL,
+ 						       mc->connection_cmd,
  						       mc->remote_server,
  						       mc->remote_username,
  						       mc->real_password,
***************
*** 949,955 ****
  			g_free (mc->real_password);
  			mc->real_password = g_strdup (mc->remote_password);
  
! 		} else if (!mc->real_password)
  			get_remote_password (mc);
  
  		check_remote_mailbox (mc);
--- 957,963 ----
  			g_free (mc->real_password);
  			mc->real_password = g_strdup (mc->remote_password);
  
! 		} else if (!mc->real_password && !mc->connection_cmd)
  			get_remote_password (mc);
  
  		check_remote_mailbox (mc);
***************
*** 1562,1567 ****
--- 1570,1587 ----
  }
  
  static void
+ connection_toggled (GtkToggleButton *button, gpointer data)
+ {
+ 	MailCheck *mc = data;
+ 	
+ 	mc->connection_enabled = gtk_toggle_button_get_active (button);
+ 	panel_applet_gconf_set_bool(mc->applet, "connection_enabled", 
+ 				    mc->connection_enabled, NULL);
+ 	soft_set_sensitive (mc->connection_cmd_entry, mc->connection_enabled);
+ 
+ }
+ 
+ static void
  remote_password_save_toggled (GtkToggleButton *button, gpointer data)
  {
  	MailCheck *mc = data;
***************
*** 1602,1607 ****
--- 1622,1646 ----
  }
  
  static void
+ connection_changed (GtkEntry *entry, gpointer data)
+ {
+ 	MailCheck *mc = data;
+ 	gchar *text;
+ 	
+ 	text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
+ 	if (!text)
+ 		return;
+ 		
+ 	if (mc->connection_cmd)
+ 		g_free (mc->connection_cmd);	
+ 	mc->connection_cmd = g_strdup (text);
+ 	panel_applet_gconf_set_string(mc->applet, "connection_command", 
+ 				      mc->connection_cmd, NULL);
+ 	g_free (text);
+ 	
+ }
+ 
+ static void
  newmail_toggled (GtkToggleButton *button, gpointer data)
  {
  	MailCheck *mc = data;
***************
*** 2173,2179 ****
  	gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0);
  	gtk_widget_show (control_vbox);
  
! 	table = gtk_table_new (3, 2, FALSE);
  	gtk_table_set_col_spacings (GTK_TABLE (table), 12);
  	gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  	gtk_container_set_border_width (GTK_CONTAINER (table), 0);
--- 2212,2218 ----
  	gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0);
  	gtk_widget_show (control_vbox);
  
! 	table = gtk_table_new (4, 2, FALSE);
  	gtk_table_set_col_spacings (GTK_TABLE (table), 12);
  	gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  	gtk_container_set_border_width (GTK_CONTAINER (table), 0);
***************
*** 2209,2220 ****
  	if ( ! key_writable (mc->applet, "exec_command"))
  		hard_set_sensitive (mc->pre_check_cmd_entry, FALSE);
  
  	l = gtk_check_button_new_with_mnemonic (_("When new mail _arrives:"));
  	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(l), mc->newmail_enabled);
  	g_signal_connect(G_OBJECT(l), "toggled",
  			   G_CALLBACK(newmail_toggled), mc);
  	gtk_widget_show(l);
! 	gtk_table_attach (GTK_TABLE (table), l, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
  	mc->newmail_cmd_check = l;
  	if ( ! key_writable (mc->applet, "newmail_enabled"))
  		hard_set_sensitive (l, FALSE);
--- 2248,2288 ----
  	if ( ! key_writable (mc->applet, "exec_command"))
  		hard_set_sensitive (mc->pre_check_cmd_entry, FALSE);
  
+ 	l = gtk_check_button_new_with_mnemonic(_("Establish _connection:"));
+ 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(l), mc->connection_enabled);
+ 	g_signal_connect(G_OBJECT(l), "toggled",
+ 			   G_CALLBACK(connection_toggled), mc);
+ 	gtk_widget_show(l);
+ 	mc->connection_cmd_check = l;
+ 	if ( ! key_writable (mc->applet, "connection_enabled"))
+ 		hard_set_sensitive (l, FALSE);
+ 
+ 	gtk_table_attach (GTK_TABLE (table), mc->connection_cmd_check, 
+ 			  0, 1, 1, 2, GTK_FILL, 0, 0, 0);
+ 			   
+ 
+ 	mc->connection_cmd_entry = gtk_entry_new();
+ 	if(mc->connection_cmd)
+ 		gtk_entry_set_text(GTK_ENTRY(mc->connection_cmd_entry), 
+ 				   mc->connection_cmd);
+ 	set_atk_name_description (mc->connection_cmd_entry, _("Command to execute to establish POP/IMAP connection"), "");
+ 	set_atk_relation (mc->connection_cmd_entry, mc->connection_cmd_check, ATK_RELATION_CONTROLLED_BY);
+ 	set_atk_relation (mc->connection_cmd_check, mc->connection_cmd_entry, ATK_RELATION_CONTROLLER_FOR);
+ 	soft_set_sensitive (mc->connection_cmd_entry, mc->connection_enabled);
+ 	g_signal_connect(G_OBJECT(mc->connection_cmd_entry), "changed",
+ 			   G_CALLBACK(connection_changed), mc);
+ 	gtk_widget_show(mc->connection_cmd_entry);
+ 	gtk_table_attach_defaults (GTK_TABLE (table), mc->connection_cmd_entry,
+ 				   1, 2, 1, 2);
+ 	if ( ! key_writable (mc->applet, "connection_command"))
+ 		hard_set_sensitive (mc->connection_cmd_entry, FALSE);
+ 
  	l = gtk_check_button_new_with_mnemonic (_("When new mail _arrives:"));
  	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(l), mc->newmail_enabled);
  	g_signal_connect(G_OBJECT(l), "toggled",
  			   G_CALLBACK(newmail_toggled), mc);
  	gtk_widget_show(l);
! 	gtk_table_attach (GTK_TABLE (table), l, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
  	mc->newmail_cmd_check = l;
  	if ( ! key_writable (mc->applet, "newmail_enabled"))
  		hard_set_sensitive (l, FALSE);
***************
*** 2232,2238 ****
  			   G_CALLBACK(newmail_changed), mc);
  	gtk_widget_show(mc->newmail_cmd_entry);
  	gtk_table_attach_defaults (GTK_TABLE (table), mc->newmail_cmd_entry,
! 				    1, 2, 1, 2);
  	if ( ! key_writable (mc->applet, "newmail_command"))
  		hard_set_sensitive (mc->newmail_cmd_entry, FALSE);
  
--- 2300,2306 ----
  			   G_CALLBACK(newmail_changed), mc);
  	gtk_widget_show(mc->newmail_cmd_entry);
  	gtk_table_attach_defaults (GTK_TABLE (table), mc->newmail_cmd_entry,
! 				    1, 2, 2, 3);
  	if ( ! key_writable (mc->applet, "newmail_command"))
  		hard_set_sensitive (mc->newmail_cmd_entry, FALSE);
  
***************
*** 2241,2247 ****
  	g_signal_connect(G_OBJECT(l), "toggled",
  			   G_CALLBACK(clicked_toggled), mc);
          gtk_widget_show(l);
! 	gtk_table_attach (GTK_TABLE (table), l, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
  	mc->clicked_cmd_check = l;
  	if ( ! key_writable (mc->applet, "clicked_enabled"))
  		hard_set_sensitive (l, FALSE);
--- 2309,2315 ----
  	g_signal_connect(G_OBJECT(l), "toggled",
  			   G_CALLBACK(clicked_toggled), mc);
          gtk_widget_show(l);
! 	gtk_table_attach (GTK_TABLE (table), l, 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
  	mc->clicked_cmd_check = l;
  	if ( ! key_writable (mc->applet, "clicked_enabled"))
  		hard_set_sensitive (l, FALSE);
***************
*** 2259,2265 ****
                             G_CALLBACK(clicked_changed), mc);
          gtk_widget_show(mc->clicked_cmd_entry);
  	gtk_table_attach_defaults (GTK_TABLE (table), mc->clicked_cmd_entry,
! 				   1, 2, 2, 3);
  	if ( ! key_writable (mc->applet, "clicked_command"))
  		hard_set_sensitive (mc->clicked_cmd_entry, FALSE);
  
--- 2327,2333 ----
                             G_CALLBACK(clicked_changed), mc);
          gtk_widget_show(mc->clicked_cmd_entry);
  	gtk_table_attach_defaults (GTK_TABLE (table), mc->clicked_cmd_entry,
! 				   1, 2, 3, 4);
  	if ( ! key_writable (mc->applet, "clicked_command"))
  		hard_set_sensitive (mc->clicked_cmd_entry, FALSE);
  
***************
*** 2395,2400 ****
--- 2463,2470 ----
  	mc->update_freq = panel_applet_gconf_get_int(mc->applet, "update_frequency", NULL);
  	mc->pre_check_cmd = panel_applet_gconf_get_string(mc->applet, "exec_command", NULL);
  	mc->pre_check_enabled = panel_applet_gconf_get_bool(mc->applet, "exec_enabled", NULL);
+ 	mc->connection_cmd = panel_applet_gconf_get_string(mc->applet, "connection_command", NULL);
+ 	mc->connection_enabled = panel_applet_gconf_get_bool(mc->applet, "connection_enabled", NULL);
  	mc->newmail_cmd = panel_applet_gconf_get_string(mc->applet, "newmail_command", NULL);
  	mc->newmail_enabled = panel_applet_gconf_get_bool(mc->applet, "newmail_enabled", NULL);
  	mc->clicked_cmd = panel_applet_gconf_get_string(mc->applet, "clicked_command", NULL);
diff -cr gnome-applets-2.4.2.orig/mailcheck/popcheck.c gnome-applets-2.4.2/mailcheck/popcheck.c
*** gnome-applets-2.4.2.orig/mailcheck/popcheck.c	Mon Sep 15 23:24:58 2003
--- gnome-applets-2.4.2/mailcheck/popcheck.c	Wed Apr 21 18:04:06 2004
***************
*** 29,34 ****
--- 29,35 ----
  static int get_server_port(const char *);
  static char* get_server_hostname(const char *);
  static int connect_socket(const char *, int);
+ static int connect_command(const char *);
  static char *read_line(int);
  static int write_line(int, char *);
  static int is_pop3_answer_ok(const char *);
***************
*** 221,226 ****
--- 222,260 ----
    return fd; 
   }  
  
+ static int connect_command(const char *cmd)
+  {
+   int socks[2], child;
+   
+   if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0)
+    {
+     return NETWORK_ERROR;
+    }
+   
+   if ((child = fork()) == -1)
+    {
+     close(socks[0]);
+     close(socks[1]);
+     return NETWORK_ERROR;
+    }
+   
+   if (!child)
+    {
+     setsid();
+     close(socks[1]);
+     close(0);
+     dup(socks[0]);
+     close(1);
+     dup(socks[0]);
+     close(socks[0]);
+     execl("/bin/sh", "sh", "-c", cmd, NULL);
+     exit(1);
+    }
+   
+   close(socks[0]);
+   return socks[1];
+  }  
+ 
  static char *read_line(int s)
   {
    static char response[1024];
***************
*** 284,290 ****
    return 0;
   }
  
! int pop3_check(const char *h, const char* n, const char* e)
  {
    int s;
    char *c;
--- 318,324 ----
    return 0;
   }
  
! int pop3_check(const char *cmd, const char *h, const char* n, const char* e)
  {
    int s;
    char *c;
***************
*** 293,299 ****
    
    if (!h || !n || !e) return -1;
    
!   s = connect_socket(h, 110);
  
    if (s > 0) {
      if (!is_pop3_answer_ok(read_line(s))) {
--- 327,335 ----
    
    if (!h || !n || !e) return -1;
    
!   if (cmd && cmd[0])
!   	s = connect_command(cmd);
!   else  s = connect_socket(h, 110);
  
    if (s > 0) {
      if (!is_pop3_answer_ok(read_line(s))) {
***************
*** 362,367 ****
--- 398,421 ----
    return 0;
   }
  
+ static int is_imap_answer_preauth(const char *p)
+  {
+   if (p) 
+    {
+     const char *b = strchr(p, ' ');
+     if (b)
+      {
+       if (*(++b) == 'P' && *(++b) == 'R' &&
+           *(++b) == 'E' && *(++b) == 'A' &&
+           *(++b) == 'U' && *(++b) == 'T' &&
+           *(++b) == 'H') 
+        return 1;
+      }
+    }
+   
+   return 0;
+  }
+ 
  static char *wait_for_imap_answer(int s, char *tag)
   {
    char *p;
***************
*** 378,384 ****
   }
  
  int 
! imap_check(const char *h, const char* n, const char* e, const char* f)
  {
  	int s;
  	char *c = NULL;
--- 432,438 ----
   }
  
  int 
! imap_check(const char *cmd, const char *h, const char* n, const char* e, const char* f)
  {
  	int s;
  	char *c = NULL;
***************
*** 387,420 ****
  	int total = 0, unseen = 0;
  	int count = 0;
  	
! 	if (!h || !n || !e) return NO_SERVER_INFO;
  	
  	if (f == NULL ||
  	    f[0] == '\0')
  		f = "INBOX";
  	
! 	s = connect_socket(h, 143);
  	
  	if (s < 0)
  		return s;
  	
  	x = read_line(s);
  	/* The greeting us untagged */
  	if (!is_imap_answer_untagged(x))
  		goto return_from_imap_check;
  	
! 	if (!is_imap_answer_ok(x))
! 		goto return_from_imap_check;
! 	
! 	
! 	c = g_strdup_printf("A1 LOGIN \"%s\" \"%s\"", n, e);
! 	if (!write_line(s, c))
  		goto return_from_imap_check;
  	
! 	if (!is_imap_answer_ok(wait_for_imap_answer(s, "A1"))) {
! 		g_free (c);
! 		close (s);
! 		return INVALID_PASS;
  	}
  	
  	c = g_strdup_printf("A2 STATUS \"%s\" (MESSAGES UNSEEN)",f);
--- 441,480 ----
  	int total = 0, unseen = 0;
  	int count = 0;
  	
! 	if (!cmd && (!h || !n || !e)) return NO_SERVER_INFO;
  	
  	if (f == NULL ||
  	    f[0] == '\0')
  		f = "INBOX";
  	
! 	if (cmd && cmd[0])
! 		s = connect_command(cmd);
! 	else	s = connect_socket(h, 143);
  	
  	if (s < 0)
  		return s;
  	
  	x = read_line(s);
+ 	
  	/* The greeting us untagged */
  	if (!is_imap_answer_untagged(x))
  		goto return_from_imap_check;
  	
! 	if (!is_imap_answer_ok(x) &&
! 	    !is_imap_answer_preauth(x))
  		goto return_from_imap_check;
  	
! 	/* tunneled connections are often preauthenticated */
! 	if (!is_imap_answer_preauth(x)) {
! 		c = g_strdup_printf("A1 LOGIN \"%s\" \"%s\"", n, e);
! 		if (!write_line(s, c))
! 			goto return_from_imap_check;
! 		
! 		if (!is_imap_answer_ok(wait_for_imap_answer(s, "A1"))) {
! 			g_free (c);
! 			close (s);
! 			return INVALID_PASS;
! 		}
  	}
  	
  	c = g_strdup_printf("A2 STATUS \"%s\" (MESSAGES UNSEEN)",f);
diff -cr gnome-applets-2.4.2.orig/mailcheck/popcheck.h gnome-applets-2.4.2/mailcheck/popcheck.h
*** gnome-applets-2.4.2.orig/mailcheck/popcheck.h	Thu Mar  6 07:16:26 2003
--- gnome-applets-2.4.2/mailcheck/popcheck.h	Wed Apr 21 17:24:58 2004
***************
*** 11,24 ****
  /* Returns how many mails are available on POP3-server "h" with username "n" and password "e"
   * The server-name may be given with or without port-number in form "host:port". 
   */
! int pop3_check(const char *h, const char* n, const char* e);
  
  /* Returns how many mails are available on IMAP-server "h"
   *     in folder "f" with username "n" and password "e"
   * Hi: unseen/recent; Lo: total
   * The server-name may be given with or without port-number in form "host:port".
   */
! int imap_check(const char *h, const char* n, const char* e, const char* f);
  
  #define NO_SERVER_INFO		-1
  #define NETWORK_ERROR		-2
--- 11,24 ----
  /* Returns how many mails are available on POP3-server "h" with username "n" and password "e"
   * The server-name may be given with or without port-number in form "host:port". 
   */
! int pop3_check(const char *c, const char *h, const char* n, const char* e);
  
  /* Returns how many mails are available on IMAP-server "h"
   *     in folder "f" with username "n" and password "e"
   * Hi: unseen/recent; Lo: total
   * The server-name may be given with or without port-number in form "host:port".
   */
! int imap_check(const char *c, const char *h, const char* n, const char* e, const char* f);
  
  #define NO_SERVER_INFO		-1
  #define NETWORK_ERROR		-2
diff -cr gnome-applets-2.4.2.orig/mailcheck/remote-helper.c gnome-applets-2.4.2/mailcheck/remote-helper.c
*** gnome-applets-2.4.2.orig/mailcheck/remote-helper.c	Thu Mar  6 07:16:26 2003
--- gnome-applets-2.4.2/mailcheck/remote-helper.c	Wed Apr 21 17:23:50 2004
***************
*** 185,191 ****
  		   gpointer data,
  		   GDestroyNotify destroy_notify,
  		   const char *command,
! 		   const char *h, const char* n, const char* e)
  {
  	RemoteHandlerData *handler_data;
  
--- 185,191 ----
  		   gpointer data,
  		   GDestroyNotify destroy_notify,
  		   const char *command,
! 		   const char *c, const char *h, const char* n, const char* e)
  {
  	RemoteHandlerData *handler_data;
  
***************
*** 195,201 ****
  	if (handler_data == NULL) {
  		int mails;
  
! 		mails = pop3_check (h, n, e);
  
  		if (mails < 0)
  			error_handler (mails, data);
--- 195,201 ----
  	if (handler_data == NULL) {
  		int mails;
  
! 		mails = pop3_check (c, h, n, e);
  
  		if (mails < 0)
  			error_handler (mails, data);
***************
*** 214,220 ****
  		    command[0] != '\0')
  			system (command);
  	       
! 		mails = pop3_check (h, n, e);
  
  		write (handler_data->fd, &mails, sizeof (mails));
  
--- 214,220 ----
  		    command[0] != '\0')
  			system (command);
  	       
! 		mails = pop3_check (c, h, n, e);
  
  		write (handler_data->fd, &mails, sizeof (mails));
  
***************
*** 229,235 ****
  		   gpointer data,
  		   GDestroyNotify destroy_notify,
  		   const char *command,
! 		   const char *h, const char* n, const char* e, const char *f)
  {
  	RemoteHandlerData *handler_data;
  
--- 229,235 ----
  		   gpointer data,
  		   GDestroyNotify destroy_notify,
  		   const char *command,
! 		   const char *c, const char *h, const char* n, const char* e, const char *f)
  {
  	RemoteHandlerData *handler_data;
  
***************
*** 239,245 ****
  	if (handler_data == NULL) {
  		int mails;
  
! 		mails = imap_check (h, n, e, f);
  
  		if (mails < 0)
  			error_handler (mails, data);
--- 239,245 ----
  	if (handler_data == NULL) {
  		int mails;
  
! 		mails = imap_check (c, h, n, e, f);
  
  		if (mails < 0)
  			error_handler (mails, data);
***************
*** 256,262 ****
  		    command[0] != '\0')
  			system (command);
  	       
! 		mails = imap_check (h, n, e, f);
  
  		write (handler_data->fd, &mails, sizeof (mails));
  
--- 256,262 ----
  		    command[0] != '\0')
  			system (command);
  	       
! 		mails = imap_check (c, h, n, e, f);
  
  		write (handler_data->fd, &mails, sizeof (mails));
  
diff -cr gnome-applets-2.4.2.orig/mailcheck/remote-helper.h gnome-applets-2.4.2/mailcheck/remote-helper.h
*** gnome-applets-2.4.2.orig/mailcheck/remote-helper.h	Thu Mar  6 07:16:26 2003
--- gnome-applets-2.4.2/mailcheck/remote-helper.h	Wed Apr 21 17:23:05 2004
***************
*** 14,25 ****
  			    gpointer data,
  			    GDestroyNotify destroy_notify,
  			    const char *command,
! 			    const char *h, const char* n, const char* e);
  gpointer helper_imap_check (RemoteHandler handler, RemoteHandler error_handler,
  			    gpointer data,
  			    GDestroyNotify destroy_notify,
  			    const char *command,
! 			    const char *h, const char* n, const char* e,
  			    const char *f);
  void helper_whack_handle (gpointer handle);
  
--- 14,25 ----
  			    gpointer data,
  			    GDestroyNotify destroy_notify,
  			    const char *command,
! 			    const char *c, const char *h, const char* n, const char* e);
  gpointer helper_imap_check (RemoteHandler handler, RemoteHandler error_handler,
  			    gpointer data,
  			    GDestroyNotify destroy_notify,
  			    const char *command,
! 			    const char *c, const char *h, const char* n, const char* e,
  			    const char *f);
  void helper_whack_handle (gpointer handle);
  


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]