updated: [8b38cf4] manully merged 227_replace_g_free

Enrico Weigelt, metux IT service weigelt at metux.de
Mon Feb 2 21:35:14 UTC 2009


The following commit has been merged in the master branch:
commit 8b38cf44daee3b0f92591baa97f36d722be99280
Merge: 035fa47c06127a201b4285cb35381fadfea7da67 15d7d47c1556c154a0cf93ef887a3d0b9d962511
Author: Enrico Weigelt, metux IT service <weigelt at metux.de>
Date:   Mon Feb 2 22:34:05 2009 +0100

    manully merged 227_replace_g_free

diff --combined ChangeLog
index f350557,b010f00..174e3aa
--- a/ChangeLog
+++ b/ChangeLog
@@@ -1,28 -1,10 +1,33 @@@
 +2009-02-01 Enrico Weigelt, metux ITS <weigelt at metux.de>
 +
 +	* src/util.c: fixed name_trunc() on NULL or empty parameters
 +	* src/achown.c: fixed unitialized var in init_chown_advanced()
 +	  (patch from andrew_b)
 +	* replaced gboolean by bool (from mhl/types.h)
 +
 +2009-01-31 Enrico Weigelt, metux ITS <weigelt at metux.de>, Patrick Winnertz <winnie at debian.org>, Slava Zanko <slavazanko at gmail.com>, Sergei Trofimovich  <slyfox at inbox.ru>
 +
 +	* edit/editcmd.c, mhl/escape.h, mhl/string.h, mhl/types.h, src/Makefile.am,
 +	* src/boxes.c, src/command.c, src/complete.c, src/complete.h, src/file.c,
 +	* src/find.c, src/main.c, src/panelize.c, src/util.c, src/utilunix.c,
 +	* src/widget.c, src/widget.h, src/wtools.c, vfs/fish.c:
 +	  fixed shell escaping issues in commandline completion engine
 +	* replaced buggy concat_dir_and_file() by mhl_str_dir_plus_file() (in mhl/string.h)
 +	* replaced g_snprintf() by snprintf()
 +
 +2009-01-30 Enrico Weigelt, metux ITS <weigelt at metux.de>
 +
 +	* src/Makefile.am, edit/Makefile.am vfs/Makefile.am: fixed #208
 +	  (out-of-tree builds)
 +	* syntax/Syntax, syntax/Makefile.am, syntax/vhdl.syntax: added VHDL syntax (#193)
 +	* replaced calls to g_strdup() by mhl_str_dup()
  
+ 2009-01-30 Enrico Weigelt, metux ITS <weigelt at metux.de>
+ 
+ 	* replaced calls to g_free() by mhl_mem_free()
+ 
  2009-01-29 Mikhail S. Pobolovets <styx.mp at gmail.com>
+ 
  	* lib/mc.ext.in: update for OpenOffice and StarOffice viewer.
  	  odt2txt is now used
  
@@@ -32,10 -14,8 +37,10 @@@
  	  This solves "strange" rename cases, when copying/moving is performed into
  	  deleted directory.
  
 -2009-01-27 Enrico Weigelt, metux IT service <weigelt at metux.de>
 +2009-01-27 Enrico Weigelt, metux ITS <weigelt at metux.de>
  
 +	* mhl/escape.h, src/complete.c, vfs/fish.c: introduced new type 
 +	  SHELL_ESCAPED_STR for more type safety
  	* mhl/escape.h, mhl/string.h: fixed comments to use /* ... */
  
  2009-01-27 Sergei Trofimovich  <slyfox at inbox.ru>
@@@ -43,11 -23,6 +48,11 @@@
  	* syntax/python.syntax: Added syntax highlighting for
  	pytnoh-2.6+ keywords (patch sent by NNemec)
  
 +2009-01-26 Mikhail S. Pobolovets <styx.mp at gmail.com>
 +
 +	* vfs/fish.c: Iterpret SUP.flags as port number if SUP.flags is not in
 +	  0, FISH_FLAG_COMPRESSED and FISH_FLAG_RSH. Weakness: port number
 +
  2009-01-25 Ilia Maslakov <il.smind at gmail.com>
  
  	* src/boxes.c, src/boxes.h, src/dir.c, src/dir.h:
@@@ -63,7 -38,7 +68,7 @@@
  	* src/cmd.c src/option.c src/setup.c src/main.h: Automatic new directory(Mkdir, F7)
  	  name filling. Can be configured (on|off) in 'Configure options'
  
 -2009-01-25 Enrico Weigelt <weigelt at metux.de>
 +2009-01-25 Enrico Weigelt, metux ITS <weigelt at metux.de>
  
  	* edit/editcmd.c, src/cmd.c, src/ext.c, src/history.h:
  	* src/hotlist.c, src/panelize.c, src/tree.c, src/user.c: 
@@@ -72,11 -47,9 +77,11 @@@
  	  translated strings. This breaks now once every history file
  	  but afterwards this will be stable
  
 -2009-01-24 Enrico Weigelt <weigelt at metux.de>
 +2009-01-24 Enrico Weigelt, metux ITS <weigelt at metux.de>
  
  	* src/cmd.c: fixed bug #35 (do_view_cmd is now calling repaint_screen())
 +	* syntax/Syntax, syntax/nemerle.syntax: Added syntax rules 
 +	  for Nemerle source files
  
  2009-01-24 Patrick Winnertz <winnie at debian.org>
  
@@@ -84,6 -57,11 +89,6 @@@
  	  - prevent . to match a newline (\n)
  	  - match from start of line and not from cursor position
  
 -2009-01-24  Enrico Weigelt, metux IT service <weigelt at metux.de>
 -
 -	* syntax/Syntax, syntax/nemerle.syntax: Added syntax rules 
 -	  for Nemerle source files
 -
  2009-01-19 Patrick Winnertz <winnie at debian.org>
  
  	* edit/edit.h: Add two more ints
@@@ -98,7 -76,7 +103,7 @@@
  	* src/main.c: Removed unused function do_mc_filename_rename
  	* src/util.c: Removed unused struct whentm
  
 -2009-01-16 Enrico Weigelt, metux IT service <weigelt at metux.de>
 +2009-01-16 Enrico Weigelt, metux ITS <weigelt at metux.de>
  
  	* src/subshell: setting subshell pty to close-on-exec 
  	  (taken from mandriva patches)
@@@ -136,6 -114,9 +141,6 @@@
  	* syntax/Makefile.am syntax/Syntax syntax/haskell.syntax:
  	added syntax definition for Haskell (taken from rhclub-tree)
  	* syntax: added ebuild Syntax defition (taken from rhclub-tree)
 -
 -2009-01-10  Enrico Weigelt, metux ITS <weigelt at metux.de>
 -
  	* edit/editcmd.c:
  	* src/achown.c src/background.c src/boxes.c src/chmod.c:
  	* src/chown.c src/cmd.c src/command.c src/dir.c src/execute.c:
diff --combined edit/choosesyntax.c
index 47628eb,6523465..886fe90
--- a/edit/choosesyntax.c
+++ b/edit/choosesyntax.c
@@@ -18,7 -18,7 +18,8 @@@
  
  #include <config.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "edit.h"
  #include "../src/global.h"
@@@ -73,14 -73,14 +74,14 @@@ edit_syntax_dialog (void) 
  
      if ((syntax = exec_edit_syntax_dialog ((const char**) names)) < 0) {
  	for (i = 0; names[i]; i++) {
- 	    g_free (names[i]);
+ 	    mhl_mem_free (names[i]);
  	}
- 	g_free (names);
+ 	mhl_mem_free (names);
  	return;
      }
  
      old_auto_syntax = option_auto_syntax;
 -    old_syntax_type = g_strdup (option_syntax_type);
 +    old_syntax_type = mhl_str_dup (option_syntax_type);
  
      switch (syntax) {
  	case 0: /* auto syntax */
@@@ -91,8 -91,8 +92,8 @@@
  	    break;
  	default:
  	    option_auto_syntax = 0;
- 	    g_free (option_syntax_type);
+ 	    mhl_mem_free (option_syntax_type);
 -	    option_syntax_type = g_strdup (names[syntax - N_DFLT_ENTRIES]);
 +	    option_syntax_type = mhl_str_dup (names[syntax - N_DFLT_ENTRIES]);
      }
  
      /* Load or unload syntax rules if the option has changed */
@@@ -103,8 -103,8 +104,8 @@@
  	edit_load_syntax (wedit, NULL, option_syntax_type);
  
      for (i = 0; names[i]; i++) {
- 	g_free (names[i]);
+ 	mhl_mem_free (names[i]);
      }
-     g_free (names);
-     g_free (old_syntax_type);
+     mhl_mem_free (names);
+     mhl_mem_free (old_syntax_type);
  }
diff --combined edit/edit.c
index bec84d7,e68bfb2..82cca0d
--- a/edit/edit.c
+++ b/edit/edit.c
@@@ -22,6 -22,7 +22,7 @@@
  */
  
  #include <config.h>
+ 
  #include <stdio.h>
  #include <stdarg.h>
  #include <sys/types.h>
@@@ -32,7 -33,7 +33,8 @@@
  #include <sys/stat.h>
  #include <stdlib.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  
@@@ -217,7 -218,7 +219,7 @@@ edit_get_filter (const char *filename
      l = strlen (quoted_name);
      p = g_malloc (strlen (all_filters[i].read) + l + 2);
      sprintf (p, all_filters[i].read, quoted_name);
-     g_free (quoted_name);
+     mhl_mem_free (quoted_name);
      return p;
  }
  
@@@ -233,7 -234,7 +235,7 @@@ edit_get_write_filter (const char *writ
      l = strlen (writename);
      p = g_malloc (strlen (all_filters[i].write) + l + 2);
      sprintf (p, all_filters[i].write, writename);
-     g_free (writename);
+     mhl_mem_free (writename);
      return p;
  }
  
@@@ -277,7 -278,7 +279,7 @@@ edit_insert_file (WEdit *edit, const ch
  		g_string_sprintf (errmsg, _(" Error reading from pipe: %s "), p);
  		edit_error_dialog (_("Error"), errmsg->str);
  		g_string_free (errmsg, TRUE);
- 		g_free (p);
+ 		mhl_mem_free (p);
  		return 0;
  	    }
  	} else {
@@@ -285,10 -286,10 +287,10 @@@
  	    g_string_sprintf (errmsg, _(" Cannot open pipe for reading: %s "), p);
  	    edit_error_dialog (_("Error"), errmsg->str);
  	    g_string_free (errmsg, TRUE);
- 	    g_free (p);
+ 	    mhl_mem_free (p);
  	    return 0;
  	}
- 	g_free (p);
+ 	mhl_mem_free (p);
      } else {
  	int i, file, blocklen;
  	long current = edit->curs1;
@@@ -301,7 -302,7 +303,7 @@@
  		edit_insert (edit, buf[i]);
  	}
  	edit_cursor_move (edit, current - edit->curs1);
- 	g_free (buf);
+ 	mhl_mem_free (buf);
  	mc_close (file);
  	if (blocklen)
  	    return 0;
@@@ -448,7 -449,7 +450,7 @@@ edit_load_position (WEdit *edit
  
      filename = vfs_canon (edit->filename);
      load_file_position (filename, &line, &column);
-     g_free (filename);
+     mhl_mem_free (filename);
  
      edit_move_to_line (edit, line - 1);
      edit->prev_col = column;
@@@ -467,7 -468,7 +469,7 @@@ edit_save_position (WEdit *edit
  
      filename = vfs_canon (edit->filename);
      save_file_position (filename, edit->curs_line + 1, edit->curs_col);
-     g_free (filename);
+     mhl_mem_free (filename);
  }
  
  /* Clean the WEdit stricture except the widget part */
@@@ -541,7 -542,7 +543,7 @@@ edit_init (WEdit *edit, int lines, int 
      if (edit_load_file (edit)) {
  	/* edit_load_file already gives an error message */
  	if (to_free)
- 	    g_free (edit);
+ 	    mhl_mem_free (edit);
  	return 0;
      }
      edit->loading_done = 1;
@@@ -592,13 -593,13 +594,13 @@@ edit_clean (WEdit *edit
      edit_free_syntax_rules (edit);
      book_mark_flush (edit, -1);
      for (; j <= MAXBUFF; j++) {
- 	g_free (edit->buffers1[j]);
- 	g_free (edit->buffers2[j]);
+ 	mhl_mem_free (edit->buffers1[j]);
+ 	mhl_mem_free (edit->buffers2[j]);
      }
  
-     g_free (edit->undo_stack);
-     g_free (edit->filename);
-     g_free (edit->dir);
+     mhl_mem_free (edit->undo_stack);
+     mhl_mem_free (edit->filename);
+     mhl_mem_free (edit->dir);
  
      edit_purge_widget (edit);
  
@@@ -638,12 -639,12 +640,12 @@@ edit_reload (WEdit *edit, const char *f
      e = g_malloc0 (sizeof (WEdit));
      e->widget = edit->widget;
      if (!edit_init (e, lines, columns, filename, 0)) {
- 	g_free (e);
+ 	mhl_mem_free (e);
  	return 0;
      }
      edit_clean (edit);
      memcpy (edit, e, sizeof (WEdit));
-     g_free (e);
+     mhl_mem_free (e);
      return 1;
  }
  
@@@ -929,7 -930,7 +931,7 @@@ int edit_delete (WEdit * edit
      p = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1];
  
      if (!(edit->curs2 & M_EDIT_BUF_SIZE)) {
- 	g_free (edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE]);
+ 	mhl_mem_free (edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE]);
  	edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = NULL;
      }
      edit->last_byte--;
@@@ -966,7 -967,7 +968,7 @@@ edit_backspace (WEdit * edit
  
      p = *(edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE] + ((edit->curs1 - 1) & M_EDIT_BUF_SIZE));
      if (!((edit->curs1 - 1) & M_EDIT_BUF_SIZE)) {
- 	g_free (edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]);
+ 	mhl_mem_free (edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]);
  	edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = NULL;
      }
      edit->last_byte--;
@@@ -1051,7 -1052,7 +1053,7 @@@ edit_move_backward_lots (WEdit *edit, l
  	    edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] =
  		g_malloc (EDIT_BUF_SIZE);
      } else {
- 	g_free (p);
+ 	mhl_mem_free (p);
      }
  
      s = edit->curs1 & M_EDIT_BUF_SIZE;
@@@ -1089,7 -1090,7 +1091,7 @@@
  		edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] =
  		    g_malloc (EDIT_BUF_SIZE);
  	} else {
- 	    g_free (p);
+ 	    mhl_mem_free (p);
  	}
      }
      return edit_get_byte (edit, edit->curs1);
@@@ -1125,7 -1126,7 +1127,7 @@@ void edit_cursor_move (WEdit * edit, lo
  	    edit->curs2++;
  	    c = edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE][(edit->curs1 - 1) & M_EDIT_BUF_SIZE];
  	    if (!((edit->curs1 - 1) & M_EDIT_BUF_SIZE)) {
- 		g_free (edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]);
+ 		mhl_mem_free (edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]);
  		edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = NULL;
  	    }
  	    edit->curs1--;
@@@ -1149,7 -1150,7 +1151,7 @@@
  	    edit->curs1++;
  	    c = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1];
  	    if (!(edit->curs2 & M_EDIT_BUF_SIZE)) {
- 		g_free (edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE]);
+ 		mhl_mem_free (edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE]);
  		edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = 0;
  	    }
  	    edit->curs2--;
@@@ -2666,7 -2667,7 +2668,7 @@@ user_menu (WEdit * edit
      int nomark;
      struct stat status;
      long start_mark, end_mark;
 -    char *block_file = concat_dir_and_file (home_dir, BLOCK_FILE);
 +    char *block_file = mhl_str_dir_plus_file (home_dir, BLOCK_FILE);
      int rc = 0;
  
      nomark = eval_marks (edit, &start_mark, &end_mark);
@@@ -2699,5 -2700,5 +2701,5 @@@
      edit->force |= REDRAW_COMPLETELY;
  
  cleanup:
-     g_free (block_file);
+     mhl_mem_free (block_file);
  }
diff --combined edit/editcmd.c
index 33c0671,f7c93c8..2f246e7
--- a/edit/editcmd.c
+++ b/edit/editcmd.c
@@@ -37,7 -37,7 +37,8 @@@
  #include <sys/stat.h>
  #include <stdlib.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/history.h"
@@@ -166,7 -166,7 +167,7 @@@ catstrs (const char *first,...
      len++;
  
      i = (i + 1) % 16;
-     g_free (stacked[i]);
+     mhl_mem_free (stacked[i]);
  
      stacked[i] = g_malloc (len);
      va_end (ap);
@@@ -185,7 -185,7 +186,7 @@@ void freestrs(void
      size_t i;
  
      for (i = 0; i < sizeof(stacked) / sizeof(stacked[0]); i++) {
- 	g_free (stacked[i]);
+ 	mhl_mem_free (stacked[i]);
  	stacked[i] = NULL;
      }
  }
@@@ -235,9 -235,9 +236,9 @@@ edit_save_file (WEdit *edit, const cha
  	return 0;
  
      if (*filename != PATH_SEP && edit->dir) {
 -	savename = concat_dir_and_file (edit->dir, filename);
 +	savename = mhl_str_dir_plus_file (edit->dir, filename);
  	filename = catstrs (savename, (char *) NULL);
- 	g_free (savename);
+ 	mhl_mem_free (savename);
      }
  
      this_save_mode = option_save_mode;
@@@ -297,11 -297,11 +298,11 @@@
  	const char *slashpos;
  	slashpos = strrchr (filename, PATH_SEP);
  	if (slashpos) {
 -	    savedir = g_strdup (filename);
 +	    savedir = mhl_str_dup (filename);
  	    savedir[slashpos - filename + 1] = '\0';
  	} else
 -	    savedir = g_strdup (".");
 -	saveprefix = concat_dir_and_file (savedir, "cooledit");
 +	    savedir = mhl_str_dup (".");
 +	saveprefix = mhl_str_dir_plus_file (savedir, "cooledit");
  	mhl_mem_free (savedir);
  	fd = mc_mkstemps (&savename, saveprefix, NULL);
  	mhl_mem_free (saveprefix);
@@@ -314,7 -314,7 +315,7 @@@
  	 */
  	close (fd);
      } else
 -	savename = g_strdup (filename);
 +	savename = mhl_str_dup (filename);
  
      mc_chown (savename, edit->stat1.st_uid, edit->stat1.st_gid);
      mc_chmod (savename, edit->stat1.st_mode);
@@@ -340,7 -340,7 +341,7 @@@
  		edit_error_dialog (_("Error"),
  				   catstrs (_(" Error writing to pipe: "),
  					    p, " ", (char *) NULL));
- 		g_free (p);
+ 		mhl_mem_free (p);
  		goto error_save;
  	    }
  #endif
@@@ -350,10 -350,10 +351,10 @@@
  					      (_
  					       (" Cannot open pipe for writing: "),
  					       p, " ", (char *) NULL)));
- 	    g_free (p);
+ 	    mhl_mem_free (p);
  	    goto error_save;
  	}
- 	g_free (p);
+ 	mhl_mem_free (p);
      } else {
  	long buf;
  	buf = 0;
@@@ -414,14 -414,14 +415,14 @@@
      if (this_save_mode != EDIT_QUICK_SAVE)
  	if (mc_rename (savename, filename) == -1)
  	    goto error_save;
-     g_free (savename);
+     mhl_mem_free (savename);
      return 1;
    error_save:
  /*  FIXME: Is this safe ?
   *  if (this_save_mode != EDIT_QUICK_SAVE)
   *	mc_unlink (savename);
   */
-     g_free (savename);
+     mhl_mem_free (savename);
      return 0;
  }
  
@@@ -492,7 -492,7 +493,7 @@@ void menu_save_mode_cmd (void
  	return;
      option_save_mode = save_mode_new;
  
-     g_free (option_backup_ext);
+     mhl_mem_free (option_backup_ext);
      option_backup_ext = str_result;
      str_result = NULL;
  }
@@@ -500,13 -500,13 +501,13 @@@
  void
  edit_set_filename (WEdit *edit, const char *f)
  {
-     g_free (edit->filename);
+     mhl_mem_free (edit->filename);
      if (!f)
  	f = "";
 -    edit->filename = g_strdup (f);
 +    edit->filename = mhl_str_dup (f);
      if (edit->dir == NULL && *f != PATH_SEP)
  #ifdef USE_VFS
 -	edit->dir = g_strdup (vfs_get_current_dir ());
 +	edit->dir = mhl_str_dup (vfs_get_current_dir ());
  #else
  	edit->dir = g_get_current_dir ();
  #endif
@@@ -529,7 -529,7 +530,7 @@@ edit_save_as_cmd (WEdit *edit
  
      if (exp) {
  	if (!*exp) {
- 	    g_free (exp);
+ 	    mhl_mem_free (exp);
  	    edit->force |= REDRAW_COMPLETELY;
  	    return 0;
  	} else {
@@@ -546,7 -546,7 +547,7 @@@
  			 _(" A file already exists with this name. "),
  			 _("&Overwrite"), _("&Cancel"))) {
  			edit->force |= REDRAW_COMPLETELY;
- 			g_free (exp);
+ 			mhl_mem_free (exp);
  			return 0;
  		    }
  		}
@@@ -572,7 -572,7 +573,7 @@@
  		}
  
  		edit_set_filename (edit, exp);
- 		g_free (exp);
+ 		mhl_mem_free (exp);
  		edit->modified = 0;
  		edit->delete_file = 0;
  		if (different_filename)
@@@ -588,7 -588,7 +589,7 @@@
  		/* Failed, so maintain modify (not save) lock */
  		if (save_lock)
  		    edit_unlock_file (exp);
- 		g_free (exp);
+ 		mhl_mem_free (exp);
  		edit->force |= REDRAW_COMPLETELY;
  		return 0;
  	    }
@@@ -626,7 -626,7 +627,7 @@@ edit_raw_key_query (const char *heading
  		    NULL, heading,
  		    DLG_CENTER | DLG_TRYUP | DLG_WANT_TAB);
      add_widget (raw_dlg,
 -		input_new (3 - cancel, w - 5, INPUT_COLOR, 2, "", 0));
 +		input_new (3 - cancel, w - 5, INPUT_COLOR, 2, "", 0, INPUT_COMPLETE_DEFAULT));
      add_widget (raw_dlg, label_new (3 - cancel, 2, query));
      if (cancel)
  	add_widget (raw_dlg,
@@@ -877,16 -877,16 +878,16 @@@ static in
  edit_load_file_from_filename (WEdit * edit, char *exp)
  {
      int prev_locked = edit->locked;
 -    char *prev_filename = g_strdup (edit->filename);
 +    char *prev_filename = mhl_str_dup (edit->filename);
  
      if (!edit_reload (edit, exp)) {
- 	g_free (prev_filename);
+ 	mhl_mem_free (prev_filename);
  	return 1;
      }
  
      if (prev_locked)
  	edit_unlock_file (prev_filename);
-     g_free (prev_filename);
+     mhl_mem_free (prev_filename);
      return 0;
  }
  
@@@ -912,7 -912,7 +913,7 @@@ edit_load_cmd (WEdit *edit
      if (exp) {
  	if (*exp)
  	    edit_load_file_from_filename (edit, exp);
- 	g_free (exp);
+ 	mhl_mem_free (exp);
      }
      edit->force |= REDRAW_COMPLETELY;
      return 0;
@@@ -1013,7 -1013,7 +1014,7 @@@ edit_block_copy_cmd (WEdit *edit
  	    edit_insert_ahead (edit, copy_buf[size]);
      }
  
-     g_free (copy_buf);
+     mhl_mem_free (copy_buf);
      edit_scroll_screen_over_cursor (edit);
  
      if (column_highlighting) {
@@@ -1114,7 -1114,7 +1115,7 @@@ edit_block_move_cmd (WEdit *edit
  			  edit->curs1 + end_mark - start_mark, 0, 0);
      }
      edit_scroll_screen_over_cursor (edit);
-     g_free (copy_buf);
+     mhl_mem_free (copy_buf);
      edit->force |= REDRAW_PAGE;
  }
  
@@@ -1450,7 -1450,7 +1451,7 @@@ string_regexp_search (char *pattern, ch
  	|| old_type != match_type || old_icase != icase) {
  	if (old_pattern) {
  	    regfree (&r);
- 	    g_free (old_pattern);
+ 	    mhl_mem_free (old_pattern);
  	    old_pattern = 0;
  	}
  	if (regcomp (&r, pattern, REG_EXTENDED | (icase ? REG_ICASE : 0) |
@@@ -1458,7 -1458,7 +1459,7 @@@
  	    *found_len = 0;
  	    return -3;
  	}
 -	old_pattern = g_strdup (pattern);
 +	old_pattern = mhl_str_dup (pattern);
  	old_type = match_type;
  	old_icase = icase;
      }
@@@ -1826,9 -1826,9 +1827,9 @@@ edit_replace_cmd (WEdit *edit, int agai
      int argord[NUM_REPL_ARGS];
  
      if (!edit) {
- 	g_free (saved1), saved1 = NULL;
- 	g_free (saved2), saved2 = NULL;
- 	g_free (saved3), saved3 = NULL;
+ 	mhl_mem_free (saved1), saved1 = NULL;
+ 	mhl_mem_free (saved2), saved2 = NULL;
+ 	mhl_mem_free (saved3), saved3 = NULL;
  	return;
      }
  
@@@ -1840,13 -1840,13 +1841,13 @@@
  	again = 0;
  
      if (again) {
 -	input1 = g_strdup (saved1 ? saved1 : "");
 -	input2 = g_strdup (saved2 ? saved2 : "");
 -	input3 = g_strdup (saved3 ? saved3 : "");
 +	input1 = mhl_str_dup (saved1 ? saved1 : "");
 +	input2 = mhl_str_dup (saved2 ? saved2 : "");
 +	input3 = mhl_str_dup (saved3 ? saved3 : "");
      } else {
 -	char *disp1 = g_strdup (saved1 ? saved1 : "");
 -	char *disp2 = g_strdup (saved2 ? saved2 : "");
 -	char *disp3 = g_strdup (saved3 ? saved3 : "");
 +	char *disp1 = mhl_str_dup (saved1 ? saved1 : "");
 +	char *disp2 = mhl_str_dup (saved2 ? saved2 : "");
 +	char *disp3 = mhl_str_dup (saved3 ? saved3 : "");
  
  	convert_to_display (disp1);
  	convert_to_display (disp2);
@@@ -1856,9 -1856,9 +1857,9 @@@
  	edit_replace_dialog (edit, disp1, disp2, disp3, &input1, &input2,
  			     &input3);
  
- 	g_free (disp1);
- 	g_free (disp2);
- 	g_free (disp3);
+ 	mhl_mem_free (disp1);
+ 	mhl_mem_free (disp2);
+ 	mhl_mem_free (disp3);
  
  	convert_from_input (input1);
  	convert_from_input (input2);
@@@ -1870,10 -1870,10 +1871,9 @@@
  	    goto cleanup;
  	}
  
- 	g_free (saved1), saved1 = mhl_str_dup (input1);
- 	g_free (saved2), saved2 = mhl_str_dup (input2);
- 	g_free (saved3), saved3 = mhl_str_dup (input3);
- 
 -	mhl_mem_free (saved1), saved1 = g_strdup (input1);
 -	mhl_mem_free (saved2), saved2 = g_strdup (input2);
 -	mhl_mem_free (saved3), saved3 = g_strdup (input3);
 -
++	mhl_mem_free (saved1), saved1 = mhl_str_dup (input1);
++	mhl_mem_free (saved2), saved2 = mhl_str_dup (input2);
++	mhl_mem_free (saved3), saved3 = mhl_str_dup (input3);
      }
  
      {
@@@ -2064,9 -2064,9 +2064,9 @@@
      edit->force = REDRAW_COMPLETELY;
      edit_scroll_screen_over_cursor (edit);
    cleanup:
-     g_free (input1);
-     g_free (input2);
-     g_free (input3);
+     mhl_mem_free (input1);
+     mhl_mem_free (input2);
+     mhl_mem_free (input3);
  }
  
  
@@@ -2078,7 -2078,7 +2078,7 @@@ void edit_search_cmd (WEdit * edit, in
      char *exp = "";
  
      if (!edit) {
- 	g_free (old);
+ 	mhl_mem_free (old);
  	old = NULL;
  	return;
      }
@@@ -2087,7 -2087,7 +2087,7 @@@
      if (again) {		/*ctrl-hotkey for search again. */
  	if (!old)
  	    return;
 -	exp = g_strdup (old);
 +	exp = mhl_str_dup (old);
      } else {
  
  #ifdef HAVE_CHARSET
@@@ -2108,8 -2108,8 +2108,8 @@@
      if (exp) {
  	if (*exp) {
  	    int len = 0;
- 	    g_free (old);
+ 	    mhl_mem_free (old);
 -	    old = g_strdup (exp);
 +	    old = mhl_str_dup (exp);
  
  	    if (search_create_bookmark) {
  		int found = 0, books = 0;
@@@ -2165,7 -2165,7 +2165,7 @@@
  		}
  	    }
  	}
- 	g_free (exp);
+ 	mhl_mem_free (exp);
      }
      edit->force |= REDRAW_COMPLETELY;
      edit_scroll_screen_over_cursor (edit);
@@@ -2204,7 -2204,7 +2204,7 @@@ edit_ok_to_exit (WEdit *edit
  
  #define TEMP_BUF_LEN 1024
  
- /* Return a null terminated length of text. Result must be g_free'd */
+ /* Return a null terminated length of text. Result must be mhl_mem_free'd */
  static unsigned char *
  edit_get_block (WEdit *edit, long start, long finish, int *l)
  {
@@@ -2257,7 -2257,7 +2257,7 @@@ edit_save_block (WEdit * edit, const ch
  	    p += r;
  	    len -= r;
  	}
- 	g_free (block);
+ 	mhl_mem_free (block);
      } else {
  	unsigned char *buf;
  	int i = start, end;
@@@ -2270,7 -2270,7 +2270,7 @@@
  	    len -= mc_write (file, (char *) buf, end - start);
  	    start = end;
  	}
- 	g_free (buf);
+ 	mhl_mem_free (buf);
      }
      mc_close (file);
      if (len)
@@@ -2337,20 -2337,20 +2337,20 @@@ edit_goto_cmd (WEdit *edit
      char *error;
      char s[32];
  
 -    g_snprintf (s, sizeof (s), "%ld", line);
 +    snprintf (s, sizeof (s), "%ld", line);
      f = input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE,
  		      line ? s : "");
      if (!f)
  	return;
  
      if (!*f) {
- 	g_free (f);
+ 	mhl_mem_free (f);
  	return;
      }
  
      l = strtol (f, &error, 0);
      if (*error) {
- 	g_free (f);
+ 	mhl_mem_free (f);
  	return;
      }
  
@@@ -2360,7 -2360,7 +2360,7 @@@
      edit_move_display (edit, l - edit->num_widget_lines / 2 - 1);
      edit_move_to_line (edit, l - 1);
      edit->force |= REDRAW_COMPLETELY;
-     g_free (f);
+     mhl_mem_free (f);
  }
  
  
@@@ -2379,15 -2379,15 +2379,15 @@@ edit_save_block_cmd (WEdit *edit
      edit_push_action (edit, KEY_PRESS + edit->start_display);
      if (exp) {
  	if (!*exp) {
- 	    g_free (exp);
+ 	    mhl_mem_free (exp);
  	    return 0;
  	} else {
  	    if (edit_save_block (edit, exp, start_mark, end_mark)) {
- 		g_free (exp);
+ 		mhl_mem_free (exp);
  		edit->force |= REDRAW_COMPLETELY;
  		return 1;
  	    } else {
- 		g_free (exp);
+ 		mhl_mem_free (exp);
  		edit_error_dialog (_(" Save Block "),
  				   get_sys_error (_
  						  (" Cannot save file. ")));
@@@ -2409,15 -2409,15 +2409,15 @@@ edit_insert_file_cmd (WEdit *edit
      edit_push_action (edit, KEY_PRESS + edit->start_display);
      if (exp) {
  	if (!*exp) {
- 	    g_free (exp);
+ 	    mhl_mem_free (exp);
  	    return 0;
  	} else {
  	    if (edit_insert_file (edit, exp)) {
- 		g_free (exp);
+ 		mhl_mem_free (exp);
  		edit->force |= REDRAW_COMPLETELY;
  		return 1;
  	    } else {
- 		g_free (exp);
+ 		mhl_mem_free (exp);
  		edit_error_dialog (_(" Insert File "),
  				   get_sys_error (_
  						  (" Cannot insert file. ")));
@@@ -2448,7 -2448,7 +2448,7 @@@ int edit_sort_cmd (WEdit * edit
  
      if (!exp)
  	return 1;
-     g_free (old);
+     mhl_mem_free (old);
      old = exp;
  
      e = system (catstrs (" sort ", exp, " ", home_dir, PATH_SEP_STR BLOCK_FILE, " > ", home_dir, PATH_SEP_STR TEMP_FILE, (char *) NULL));
@@@ -2492,7 -2492,7 +2492,7 @@@ edit_ext_cmd (WEdit *edit
  	return 1;
  
      e = system (catstrs (exp, " > ", home_dir, PATH_SEP_STR TEMP_FILE, (char *) NULL));
-     g_free (exp);
+     mhl_mem_free (exp);
  
      if (e) {
  	edit_error_dialog (_("External command"),
@@@ -2588,7 -2588,7 +2588,7 @@@ edit_block_process_cmd (WEdit *edit, co
  	system (catstrs (" ", home_dir, PATH_SEP_STR EDIT_DIR, shell_cmd, " ",
  			 quoted_name, (char *) NULL));
      }
-     g_free (quoted_name);
+     mhl_mem_free (quoted_name);
      close_error_pipe (D_NORMAL, NULL);
  
      edit_refresh_cmd (edit);
@@@ -2629,13 -2629,13 +2629,13 @@@ static void pipe_mail (WEdit *edit, cha
      subject = name_quote (subject, 0);
      cc = name_quote (cc, 0);
      s = g_strconcat ("mail -s ", subject, *cc ? " -c " : "" , cc, " ",  to, (char *) NULL);
-     g_free (to);
-     g_free (subject);
-     g_free (cc);
+     mhl_mem_free (to);
+     mhl_mem_free (subject);
+     mhl_mem_free (cc);
  
      if (s) {
  	p = popen (s, "w");
- 	g_free (s);
+ 	mhl_mem_free (s);
      }
  
      if (p) {
@@@ -2694,9 -2694,9 +2694,9 @@@ void edit_mail_dialog (WEdit * edit
      Quick_input.widgets = quick_widgets;
  
      if (quick_dialog (&Quick_input) != B_CANCEL) {
- 	g_free (mail_cc_last);
- 	g_free (mail_subject_last);
- 	g_free (mail_to_last);
+ 	mhl_mem_free (mail_cc_last);
+ 	mhl_mem_free (mail_subject_last);
+ 	mhl_mem_free (mail_to_last);
  	mail_cc_last = tmail_cc;
  	mail_subject_last = tmail_subject;
  	mail_to_last = tmail_to;
@@@ -2938,10 -2938,10 +2938,10 @@@ edit_complete_word_cmd (WEdit *edit
  	}
      }
  
-     g_free (match_expr);
+     mhl_mem_free (match_expr);
      /* release memory before return */
      for (i = 0; i < num_compl; i++)
- 	g_free (compl[i].text);
+ 	mhl_mem_free (compl[i].text);
  
      /* restore search parameters */
      edit_set_search_parameters (old_rs, old_rb, old_rr, old_rw, old_rc);
diff --combined edit/editdraw.c
index b191391,9417f78..68a9033
--- a/edit/editdraw.c
+++ b/edit/editdraw.c
@@@ -34,6 -34,8 +34,8 @@@
  #include <errno.h>
  #include <sys/stat.h>
  
+ #include <mhl/memory.h>
+ 
  #include "../src/global.h"
  
  #include "edit.h"
@@@ -72,7 -74,7 +74,7 @@@ static void status_string (WEdit * edit
       */
      if (edit->curs1 < edit->last_byte) {
  	unsigned char cur_byte = edit_get_byte (edit, edit->curs1);
 -	g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X",
 +	snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X",
  		    is_printable (cur_byte) ? cur_byte : '.',
  		    (int) cur_byte,
  		    (unsigned) cur_byte);
@@@ -81,7 -83,7 +83,7 @@@
      }
  
      /* The field lengths just prevent the status line from shortening too much */
 -    g_snprintf (s, w,
 +    snprintf (s, w,
  		"[%c%c%c%c] %2ld L:[%3ld+%2ld %3ld/%3ld] *(%-4ld/%4ldb)= %s",
  		edit->mark1 != edit->mark2 ? ( column_highlighting ? 'C' : 'B') : '-',
  		edit->modified ? 'M' : '-',
@@@ -145,7 -147,7 +147,7 @@@ edit_status (WEdit *edit
      printwstr (status, w - (fname_len + gap));
      attrset (EDITOR_NORMAL_COLOR);
  
-     g_free (status);
+     mhl_mem_free (status);
  }
  
  /* this scrolls the text so that cursor is on the screen */
diff --combined edit/editlock.c
index 72e433c,247f65f..5068297
--- a/edit/editlock.c
+++ b/edit/editlock.c
@@@ -36,7 -36,7 +36,8 @@@
  #include <sys/stat.h>
  #include <stdlib.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  
@@@ -97,10 -97,10 +98,10 @@@ lock_build_symlink_name (const char *fn
  	return NULL;
  
      fname = x_basename (absolute_fname);
 -    fname_copy = g_strdup (fname);
 +    fname_copy = mhl_str_dup (fname);
      absolute_fname[fname - absolute_fname] = '\0';
      symlink_name = g_strconcat (absolute_fname, ".#", fname_copy, (char *) NULL);
-     g_free (fname_copy);
+     mhl_mem_free (fname_copy);
  
      return symlink_name;
  }
@@@ -175,7 -175,7 +176,7 @@@ edit_lock_file (const char *fname
      if (lstat (lockfname, &statbuf) == 0) {
  	lock = lock_get_info (lockfname);
  	if (!lock) {
- 	    g_free (lockfname);
+ 	    mhl_mem_free (lockfname);
  	    return 0;
  	}
  	lockinfo = lock_extract_info (lock);
@@@ -196,11 -196,11 +197,11 @@@
  		break;
  	    case 1:
  	    case -1:
- 		g_free (lockfname);
- 		g_free (msg);
+ 		mhl_mem_free (lockfname);
+ 		mhl_mem_free (msg);
  		return 0;
  	    }
- 	    g_free (msg);
+ 	    mhl_mem_free (msg);
  	}
  	unlink (lockfname);
      }
@@@ -208,13 -208,13 +209,13 @@@
      /* Create lock symlink */
      newlock = lock_build_name ();
      if (symlink (newlock, lockfname) == -1) {
- 	g_free (lockfname);
- 	g_free (newlock);
+ 	mhl_mem_free (lockfname);
+ 	mhl_mem_free (newlock);
  	return 0;
      }
  
-     g_free (lockfname);
-     g_free (newlock);
+     mhl_mem_free (lockfname);
+     mhl_mem_free (newlock);
      return 1;
  }
  
@@@ -236,7 -236,7 +237,7 @@@ edit_unlock_file (const char *fname
  
      /* Check if lock exists */
      if (lstat (lockfname, &statbuf) == -1) {
- 	g_free (lockfname);
+ 	mhl_mem_free (lockfname);
  	return 0;
      }
  
@@@ -244,13 -244,13 +245,13 @@@
      if (lock) {
  	/* Don't touch if lock is not ours */
  	if (lock_extract_info (lock)->pid != getpid ()) {
- 	    g_free (lockfname);
+ 	    mhl_mem_free (lockfname);
  	    return 0;
  	}
      }
  
      /* Remove lock */
      unlink (lockfname);
-     g_free (lockfname);
+     mhl_mem_free (lockfname);
      return 0;
  }
diff --combined edit/editoptions.c
index 777431f,a30b4ef..56785c7
--- a/edit/editoptions.c
+++ b/edit/editoptions.c
@@@ -33,9 -33,10 +33,10 @@@
  #include <ctype.h>
  #include <errno.h>
  #include <sys/stat.h>
- 
  #include <stdlib.h>
  
+ #include <mhl/memory.h>
+ 
  #include "../src/global.h"
  
  #include "edit.h"
@@@ -147,9 -148,9 +148,9 @@@ edit_options_dialog (void
  	i18n_flag = 1;
      }
  
 -    g_snprintf (wrap_length, sizeof (wrap_length), "%d",
 +    snprintf (wrap_length, sizeof (wrap_length), "%d",
  		option_word_wrap_line_length);
 -    g_snprintf (tab_spacing, sizeof (tab_spacing), "%d",
 +    snprintf (tab_spacing, sizeof (tab_spacing), "%d",
  		option_tab_spacing);
  
      quick_widgets[3].text = wrap_length;
@@@ -186,13 -187,13 +187,13 @@@
  
      if (p) {
  	option_word_wrap_line_length = atoi (p);
- 	g_free (p);
+ 	mhl_mem_free (p);
      }
      if (q) {
  	option_tab_spacing = atoi (q);
  	if (option_tab_spacing <= 0)
  	    option_tab_spacing = 8;
- 	g_free (q);
+ 	mhl_mem_free (q);
      }
  
      option_syntax_highlighting = tedit_syntax_highlighting;
diff --combined edit/editwidget.c
index 8ae8cf0,482704f..0489262
--- a/edit/editwidget.c
+++ b/edit/editwidget.c
@@@ -35,7 -35,7 +35,8 @@@
  #include <sys/stat.h>
  #include <stdlib.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  
@@@ -175,9 -175,9 +176,9 @@@ edit_file (const char *_file, int line
      WButtonBar *edit_bar;
  
      if (!made_directory) {
 -	char *dir = concat_dir_and_file (home_dir, EDIT_DIR);
 +	char *dir = mhl_str_dir_plus_file (home_dir, EDIT_DIR);
  	made_directory = (mkdir (dir, 0700) != -1 || errno == EEXIST);
- 	g_free (dir);
+ 	mhl_mem_free (dir);
      }
  
      if (!(wedit = edit_init (NULL, LINES - 2, COLS, _file, line))) {
diff --combined edit/syntax.c
index df6a47e,ca6f8a6..479f3c5
--- a/edit/syntax.c
+++ b/edit/syntax.c
@@@ -32,7 -32,7 +32,8 @@@
  #include <sys/stat.h>
  #include <stdlib.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  
@@@ -103,8 -103,8 +104,6 @@@ int option_syntax_highlighting = 1
  int option_auto_syntax = 1;
  char *option_syntax_type = NULL;
  
- #define syntax_g_free(x) do {g_free(x); (x)=0;} while (0)
- 
 -#define _FREEPTR(x) do {mhl_mem_free(x); (x)=0;} while (0)
 -
  static gint
  mc_defines_destroy (gpointer key, gpointer value, gpointer data)
  {
@@@ -112,10 -112,10 +111,10 @@@
  
      (void) data;
  
-     g_free (key);
+     mhl_mem_free (key);
      while (*values)
- 	g_free (*values++);
-     g_free (value);
+ 	mhl_mem_free (*values++);
+     mhl_mem_free (value);
  
      return FALSE;
  }
@@@ -472,7 -472,7 +471,7 @@@ static struct syntax_rule edit_get_rul
  		break;
  	    }
  	    s = edit->syntax_marker->next;
- 	    syntax_g_free (edit->syntax_marker);
 -	    _FREEPTR (edit->syntax_marker);
++	    MHL_PTR_FREE (edit->syntax_marker);
  	    edit->syntax_marker = s;
  	}
      }
@@@ -667,19 -667,19 +666,19 @@@ static FILE *open_include_file (const c
  {
      FILE *f;
  
-     syntax_g_free (error_file_name);
 -    _FREEPTR (error_file_name);
 -    error_file_name = g_strdup (filename);
++    MHL_PTR_FREE (error_file_name);
 +    error_file_name = mhl_str_dup (filename);
      if (*filename == PATH_SEP)
  	return fopen (filename, "r");
  
-     g_free (error_file_name);
+     mhl_mem_free (error_file_name);
      error_file_name = g_strconcat (home_dir, PATH_SEP_STR EDIT_DIR PATH_SEP_STR,
  				   filename, (char *) NULL);
      f = fopen (error_file_name, "r");
      if (f)
  	return f;
  
-     g_free (error_file_name);
+     mhl_mem_free (error_file_name);
      error_file_name = g_strconcat (mc_home, PATH_SEP_STR "syntax" PATH_SEP_STR,
  				   filename, (char *) NULL);
      return fopen (error_file_name, "r");
@@@ -726,8 -726,8 +725,8 @@@ edit_read_syntax_rules (WEdit *edit, FI
  		f = g;
  		g = 0;
  		line = save_line + 1;
- 		syntax_g_free (error_file_name);
- 		syntax_g_free (l);
 -		_FREEPTR (error_file_name);
 -		_FREEPTR (l);
++		MHL_PTR_FREE (error_file_name);
++		MHL_PTR_FREE (l);
  		if (!read_one_line (&l, f))
  		    break;
  	    } else {
@@@ -746,7 -746,7 +745,7 @@@
  	    g = f;
  	    f = open_include_file (args[1]);
  	    if (!f) {
- 		syntax_g_free (error_file_name);
 -		_FREEPTR (error_file_name);
++		MHL_PTR_FREE (error_file_name);
  		result = line;
  		break;
  	    }
@@@ -774,8 -774,8 +773,8 @@@
  		}
  		a++;
  		c = r[0] = g_malloc0 (sizeof (struct context_rule));
 -		c->left = g_strdup (" ");
 -		c->right = g_strdup (" ");
 +		c->left = mhl_str_dup (" ");
 +		c->right = mhl_str_dup (" ");
  		num_contexts = 0;
  	    } else {
  		/* Terminate previous context.  */
@@@ -788,14 -788,14 +787,14 @@@
  		check_a;
  		if (!strcmp (*a, "whole")) {
  		    a++;
 -		    c->whole_word_chars_left = g_strdup (whole_left);
 -		    c->whole_word_chars_right = g_strdup (whole_right);
 +		    c->whole_word_chars_left = mhl_str_dup (whole_left);
 +		    c->whole_word_chars_right = mhl_str_dup (whole_right);
  		} else if (!strcmp (*a, "wholeleft")) {
  		    a++;
 -		    c->whole_word_chars_left = g_strdup (whole_left);
 +		    c->whole_word_chars_left = mhl_str_dup (whole_left);
  		} else if (!strcmp (*a, "wholeright")) {
  		    a++;
 -		    c->whole_word_chars_right = g_strdup (whole_right);
 +		    c->whole_word_chars_right = mhl_str_dup (whole_right);
  		}
  		check_a;
  		if (!strcmp (*a, "linestart")) {
@@@ -803,14 -803,14 +802,14 @@@
  		    c->line_start_left = 1;
  		}
  		check_a;
 -		c->left = g_strdup (*a++);
 +		c->left = mhl_str_dup (*a++);
  		check_a;
  		if (!strcmp (*a, "linestart")) {
  		    a++;
  		    c->line_start_right = 1;
  		}
  		check_a;
 -		c->right = g_strdup (*a++);
 +		c->right = mhl_str_dup (*a++);
  		c->first_left = *c->left;
  		c->first_right = *c->right;
  	    }
@@@ -827,7 -827,7 +826,7 @@@
  	    g_strlcpy (last_fg, fg ? fg : "", sizeof (last_fg));
  	    g_strlcpy (last_bg, bg ? bg : "", sizeof (last_bg));
  	    c->keyword[0]->color = this_try_alloc_color_pair (fg, bg);
 -	    c->keyword[0]->keyword = g_strdup (" ");
 +	    c->keyword[0]->keyword = mhl_str_dup (" ");
  	    check_not_a;
  
  	    alloc_words_per_context = MAX_WORDS_PER_CONTEXT;
@@@ -853,14 -853,14 +852,14 @@@
  	    k = r[num_contexts - 1]->keyword[num_words] = g_malloc0 (sizeof (struct key_word));
  	    if (!strcmp (*a, "whole")) {
  		a++;
 -		k->whole_word_chars_left = g_strdup (whole_left);
 -		k->whole_word_chars_right = g_strdup (whole_right);
 +		k->whole_word_chars_left = mhl_str_dup (whole_left);
 +		k->whole_word_chars_right = mhl_str_dup (whole_right);
  	    } else if (!strcmp (*a, "wholeleft")) {
  		a++;
 -		k->whole_word_chars_left = g_strdup (whole_left);
 +		k->whole_word_chars_left = mhl_str_dup (whole_left);
  	    } else if (!strcmp (*a, "wholeright")) {
  		a++;
 -		k->whole_word_chars_right = g_strdup (whole_right);
 +		k->whole_word_chars_right = mhl_str_dup (whole_right);
  	    }
  	    check_a;
  	    if (!strcmp (*a, "linestart")) {
@@@ -871,7 -871,7 +870,7 @@@
  	    if (!strcmp (*a, "whole")) {
  		break_a;
  	    }
 -	    k->keyword = g_strdup (*a++);
 +	    k->keyword = mhl_str_dup (*a++);
  	    k->first = *k->keyword;
  	    subst_defines (edit->defines, a, &args[1024]);
  	    fg = *a;
@@@ -911,22 -911,22 +910,22 @@@
  	    if ((argv = g_tree_lookup (edit->defines, key))) {
  		mc_defines_destroy (NULL, argv, NULL);
  	    } else {
 -		key = g_strdup (key);
 +		key = mhl_str_dup (key);
  	    }
  	    argv = g_new (char *, argc - 1);
  	    g_tree_insert (edit->defines, key, argv);
  	    while (*a) {
 -		*argv++ = g_strdup (*a++);
 +		*argv++ = mhl_str_dup (*a++);
  	    };
  	    *argv = NULL;
  	} else {		/* anything else is an error */
  	    break_a;
  	}
  	free_args (args);
- 	syntax_g_free (l);
 -	_FREEPTR (l);
++	MHL_PTR_FREE (l);
      }
      free_args (args);
-     syntax_g_free (l);
 -    _FREEPTR (l);
++    MHL_PTR_FREE (l);
  
      /* Terminate context array.  */
      if (num_contexts > 0) {
@@@ -935,7 -935,7 +934,7 @@@
      }
  
      if (!edit->rules[0])
- 	syntax_g_free (edit->rules);
 -	_FREEPTR (edit->rules);
++	MHL_PTR_FREE (edit->rules);
  
      if (result)
  	return result;
@@@ -956,10 -956,10 +955,10 @@@
  	    for (j = 1; c->keyword[j]; j++)
  		*p++ = c->keyword[j]->first;
  	    *p = '\0';
 -	    c->keyword_first_chars = g_strdup (first_chars);
 +	    c->keyword_first_chars = mhl_str_dup (first_chars);
  	}
  
- 	g_free (first_chars);
+ 	mhl_mem_free (first_chars);
      }
  
      return result;
@@@ -977,34 -977,34 +976,34 @@@ void edit_free_syntax_rules (WEdit * ed
  	return;
  
      edit_get_rule (edit, -1);
-     syntax_g_free (edit->syntax_type);
 -    _FREEPTR (edit->syntax_type);
++    MHL_PTR_FREE (edit->syntax_type);
      edit->syntax_type = 0;
  
      for (i = 0; edit->rules[i]; i++) {
  	if (edit->rules[i]->keyword) {
  	    for (j = 0; edit->rules[i]->keyword[j]; j++) {
- 		syntax_g_free (edit->rules[i]->keyword[j]->keyword);
- 		syntax_g_free (edit->rules[i]->keyword[j]->whole_word_chars_left);
- 		syntax_g_free (edit->rules[i]->keyword[j]->whole_word_chars_right);
- 		syntax_g_free (edit->rules[i]->keyword[j]);
 -		_FREEPTR (edit->rules[i]->keyword[j]->keyword);
 -		_FREEPTR (edit->rules[i]->keyword[j]->whole_word_chars_left);
 -		_FREEPTR (edit->rules[i]->keyword[j]->whole_word_chars_right);
 -		_FREEPTR (edit->rules[i]->keyword[j]);
++		MHL_PTR_FREE (edit->rules[i]->keyword[j]->keyword);
++		MHL_PTR_FREE (edit->rules[i]->keyword[j]->whole_word_chars_left);
++		MHL_PTR_FREE (edit->rules[i]->keyword[j]->whole_word_chars_right);
++		MHL_PTR_FREE (edit->rules[i]->keyword[j]);
  	    }
  	}
- 	syntax_g_free (edit->rules[i]->left);
- 	syntax_g_free (edit->rules[i]->right);
- 	syntax_g_free (edit->rules[i]->whole_word_chars_left);
- 	syntax_g_free (edit->rules[i]->whole_word_chars_right);
- 	syntax_g_free (edit->rules[i]->keyword);
- 	syntax_g_free (edit->rules[i]->keyword_first_chars);
- 	syntax_g_free (edit->rules[i]);
 -	_FREEPTR (edit->rules[i]->left);
 -	_FREEPTR (edit->rules[i]->right);
 -	_FREEPTR (edit->rules[i]->whole_word_chars_left);
 -	_FREEPTR (edit->rules[i]->whole_word_chars_right);
 -	_FREEPTR (edit->rules[i]->keyword);
 -	_FREEPTR (edit->rules[i]->keyword_first_chars);
 -	_FREEPTR (edit->rules[i]);
++	MHL_PTR_FREE (edit->rules[i]->left);
++	MHL_PTR_FREE (edit->rules[i]->right);
++	MHL_PTR_FREE (edit->rules[i]->whole_word_chars_left);
++	MHL_PTR_FREE (edit->rules[i]->whole_word_chars_right);
++	MHL_PTR_FREE (edit->rules[i]->keyword);
++	MHL_PTR_FREE (edit->rules[i]->keyword_first_chars);
++	MHL_PTR_FREE (edit->rules[i]);
      }
  
      while (edit->syntax_marker) {
  	struct _syntax_marker *s = edit->syntax_marker->next;
- 	syntax_g_free (edit->syntax_marker);
 -	_FREEPTR (edit->syntax_marker);
++	MHL_PTR_FREE (edit->syntax_marker);
  	edit->syntax_marker = s;
      }
  
-     syntax_g_free (edit->rules);
 -    _FREEPTR (edit->rules);
++    MHL_PTR_FREE (edit->rules);
  }
  
  /* returns -1 on file error, line number on error in file syntax */
@@@ -1027,9 -1027,9 +1026,9 @@@ edit_read_syntax_file (WEdit * edit, ch
  
      f = fopen (syntax_file, "r");
      if (!f){
 -	lib_file = concat_dir_and_file (mc_home, "syntax" PATH_SEP_STR "Syntax");
 +	lib_file = mhl_str_dir_plus_file (mc_home, "syntax" PATH_SEP_STR "Syntax");
  	f = fopen (lib_file, "r");
- 	g_free (lib_file);
+ 	mhl_mem_free (lib_file);
  	if (!f)
  	    return -1;
      }
@@@ -1037,7 -1037,7 +1036,7 @@@
      args[0] = 0;
      for (;;) {
  	line++;
- 	syntax_g_free (l);
 -	_FREEPTR (l);
++	MHL_PTR_FREE (l);
  	if (!read_one_line (&l, f))
  	    break;
  	(void)get_args (l, args, 1023);	/* Final NULL */
@@@ -1077,7 -1077,7 +1076,7 @@@
  		else
  		    abort ();
  	    }
 -	    (*pnames)[count++] = g_strdup (args[2]);
 +	    (*pnames)[count++] = mhl_str_dup (args[2]);
  	    (*pnames)[count] = NULL;
  	} else if (type) {
  
@@@ -1118,9 -1118,9 +1117,8 @@@
  		    else
  			result = line_error;
  		} else {
- 		    syntax_g_free (edit->syntax_type);
 -		    _FREEPTR (edit->syntax_type);
 -		    edit->syntax_type = g_strdup (syntax_type);
 -
++		    MHL_PTR_FREE (edit->syntax_type);
 +		    edit->syntax_type = mhl_str_dup (syntax_type);
- 
  /* if there are no rules then turn off syntax highlighting for speed */
  		    if (!g && !edit->rules[1])
  			if (!edit->rules[0]->keyword[1] && !edit->rules[0]->spelling) {
@@@ -1137,7 -1137,7 +1135,7 @@@
  	    }
  	}
      }
-     syntax_g_free (l);
 -    _FREEPTR (l);
++    MHL_PTR_FREE (l);
      fclose (f);
      return result;
  }
@@@ -1189,7 -1189,7 +1187,7 @@@ edit_load_syntax (WEdit *edit, char ***
  	if (!*edit->filename && !type)
  	    return;
      }
 -    f = concat_dir_and_file (home_dir, SYNTAX_FILE);
 +    f = mhl_str_dir_plus_file (home_dir, SYNTAX_FILE);
      r = edit_read_syntax_file (edit, pnames, f, edit ? edit->filename : 0,
  			       get_first_editor_line (edit), type);
      if (r == -1) {
@@@ -1202,9 -1202,9 +1200,9 @@@
  	message (D_ERROR, _(" Load syntax file "),
  		 _(" Error in file %s on line %d "),
  		 error_file_name ? error_file_name : f, r);
- 	syntax_g_free (error_file_name);
 -	_FREEPTR (error_file_name);
++	MHL_PTR_FREE (error_file_name);
      } else {
  	/* succeeded */
      }
-     g_free (f);
+     mhl_mem_free (f);
  }
diff --combined edit/usermap.c
index f5d5e4f,06c073e..b25cad9
--- a/edit/usermap.c
+++ b/edit/usermap.c
@@@ -30,8 -30,7 +30,9 @@@
  #include <sys/stat.h>
  #include <unistd.h>
  
 +#include <mhl/types.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  
@@@ -58,7 -57,7 +59,7 @@@ typedef struct Config 
  
  typedef struct Command {
      const char *name;
 -    int (*handler) (config_t *cfg, int argc, char *argv[]);
 +    bool (*handler) (config_t *cfg, int argc, char *argv[]);
  } command_t;
  
  static char error_msg[200] = "Nobody see this";
@@@ -243,7 -242,7 +244,7 @@@ cfg_free_maps(config_t *cfg
      cfg->ext_keymap = NULL;
  
      for (i = 0; i < 10; i++)
- 	g_free(cfg->labels[i]);
+ 	mhl_mem_free(cfg->labels[i]);
  }
  
  /* Returns an array containing the words in str.  WARNING: As long as
@@@ -254,7 -253,7 +255,7 @@@
  static GPtrArray *
  split_line(char *str)
  {
 -    gboolean inside_quote = FALSE;
 +    bool inside_quote = false;
      int move = 0;
      GPtrArray *args;    
  
@@@ -344,7 -343,7 +345,7 @@@ keymap_add(GArray *keymap, int key, in
  }
  
  /* bind <key> <command> */
 -static gboolean
 +static bool
  cmd_bind(config_t *cfg, int argc, char *argv[])
  {
      char *keyname, *command;
@@@ -355,7 -354,7 +356,7 @@@
      if (argc != 3) {
  	snprintf(error_msg, sizeof(error_msg),
  		 _("bind: Wrong argument number, bind <key> <command>"));
 -	return FALSE;
 +	return false;
      }
  
      keyname = argv[1];
@@@ -377,7 -376,7 +378,7 @@@
  	    if (!m) {		/* incorrect key */
  		snprintf(error_msg, sizeof(error_msg),
  			 _("bind: Bad key value `%s'"), keyname);
 -		return FALSE;
 +		return false;
  	    }
  	    mod |= m;
  	    m = 0;
@@@ -390,7 -389,7 +391,7 @@@
      /* no key */
      if (keyname[0] == '\0') {
  	snprintf(error_msg, sizeof(error_msg), _("bind: Ehh...no key?"));
 -	return FALSE;
 +	return false;
      }
  
      /* ordinary key */
@@@ -404,7 -403,7 +405,7 @@@
      if (k < 0 && !key->name) {
  	snprintf(error_msg, sizeof(error_msg),
  		 _("bind: Unknown key: `%s'"), keyname);
 -	return FALSE;
 +	return false;
      }
  
      while (cmd->name && strcasecmp(cmd->name, command) != 0)
@@@ -413,7 -412,7 +414,7 @@@
      if (!cmd->name) {
  	snprintf(error_msg, sizeof(error_msg),
  		 _("bind: Unknown command: `%s'"), command);
 -	return FALSE;
 +	return false;
      }
  
      if (mod & KEY_M_CTRL) {
@@@ -434,7 -433,7 +435,7 @@@
      else
  	keymap_add(cfg->keymap, k, cmd->val);
  
 -    return TRUE;
 +    return true;
  }
  
  #if 0
@@@ -470,7 -469,7 +471,7 @@@ static void edit_my_define (Dlg_head * 
  #endif
  
  /* label <number> <command> <label> */
 -static gboolean
 +static bool
  cmd_label(config_t *cfg, int argc, char *argv[])
  {
      const name_map_t *cmd = command_names;
@@@ -481,7 -480,7 +482,7 @@@
  	snprintf(error_msg, sizeof(error_msg),
  		 _("%s: Syntax: %s <n> <command> <label>"), 
  		argv[0], argv[0]);
 -	return FALSE;
 +	return false;
      }
      
      fn	= strtol(argv[1], NULL, 0);
@@@ -494,23 -493,23 +495,23 @@@
      if (!cmd->name) {
  	snprintf(error_msg, sizeof(error_msg),
  		 _("%s: Unknown command: `%s'"), argv[0], command);
 -	return FALSE;
 +	return false;
      }
      
      if (fn < 1 || fn > 10) {
  	snprintf(error_msg, sizeof(error_msg),
  		 _("%s: fn should be 1-10"), argv[0]);
 -	return FALSE;
 +	return false;
      }
  
      keymap_add(cfg->keymap, KEY_F(fn), cmd->val);
 -    cfg->labels[fn - 1] = g_strdup(label);
 +    cfg->labels[fn - 1] = mhl_str_dup(label);
  
 -    return TRUE;
 +    return true;
  }
  
  
 -static gboolean
 +static bool
  parse_file(config_t *cfg, const char *file, const command_t *cmd)
  {
      char buf[200];
@@@ -521,7 -520,7 +522,7 @@@
      if (!fp) {
  	snprintf(error_msg, sizeof(error_msg), _("%s: fopen(): %s"),
  		 file, strerror(errno));
 -	return FALSE;
 +	return false;
      }
  
      while (fgets(buf, sizeof(buf), fp)) {
@@@ -548,26 -547,26 +549,26 @@@
  		     argv[0]);
  	    g_ptr_array_free(args, TRUE);
  	    fclose(fp);
 -	    return FALSE;
 +	    return false;
  	}
  
  	if (!(c->handler(cfg, args->len, argv))) {
 -	    char *ss = g_strdup(error_msg);
 +	    char *ss = mhl_str_dup(error_msg);
  	    snprintf(error_msg, sizeof(error_msg),
  			 _("%s:%d: %s"), file, line, ss);
- 	    g_free(ss);
+ 	    mhl_mem_free(ss);
  	    g_ptr_array_free(args, TRUE);
  	    fclose(fp);
 -	    return FALSE;
 +	    return false;
  	}
  	g_ptr_array_free(args, TRUE);
      }
  
      fclose(fp);
 -    return TRUE;
 +    return true;
  }
  
 -static gboolean
 +static bool
  load_user_keymap(config_t *cfg, const char *file)
  {
      const command_t cmd[] = {
@@@ -581,13 -580,13 +582,13 @@@
      cfg->ext_keymap = g_array_new(TRUE, FALSE, sizeof(edit_key_map_type));
  
      if (!parse_file(cfg, file, cmd)) {
 -	return FALSE;
 +	return false;
      }
  
 -    return TRUE;
 +    return true;
  }
  
 -gboolean
 +bool
  edit_load_user_map(WEdit *edit)
  {
      static config_t cfg;
@@@ -596,16 -595,16 +597,16 @@@
      struct stat s;
  
      if (edit_key_emulation != EDIT_KEY_EMULATION_USER)
 -	return TRUE;
 +	return true;
  
 -    file = concat_dir_and_file(home_dir, MC_USERMAP);
 +    file = mhl_str_dir_plus_file(home_dir, MC_USERMAP);
  
      if (stat(file, &s) < 0) {
  	char *msg = g_strdup_printf(_("%s not found!"), file);
  	edit_error_dialog(_("Error"), msg);
- 	g_free(msg);
- 	g_free(file);
+ 	mhl_mem_free(msg);
+ 	mhl_mem_free(file);
 -	return FALSE;
 +	return false;
      }
  
      if (s.st_mtime != cfg.mtime) {
@@@ -615,8 -614,8 +616,8 @@@
  	if (!load_user_keymap(&new_cfg, file)) {
  	    edit_error_dialog(_("Error"), error_msg);
  	    cfg_free_maps(&new_cfg);
- 	    g_free(file);
+ 	    mhl_mem_free(file);
 -	    return FALSE;
 +	    return false;
  	} else {
  	    cfg_free_maps(&cfg);
  	    cfg = new_cfg;
@@@ -627,7 -626,7 +628,7 @@@
      edit->ext_map = (edit_key_map_type *) cfg.ext_keymap->data;
      memcpy(edit->labels, cfg.labels, sizeof(edit->labels));
  
-     g_free(file);
+     mhl_mem_free(file);
  
 -    return TRUE;
 +    return true;
  }
diff --combined src/achown.c
index de2ae07,b723724..c68a806
--- a/src/achown.c
+++ b/src/achown.c
@@@ -22,11 -22,12 +22,12 @@@
  #include <errno.h>
  #include <stdio.h>
  #include <string.h>
- 
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <unistd.h>
  
+ #include <mhl/memory.h>
+ 
  #include "global.h"
  #include "tty.h"
  #include "win.h"
@@@ -539,9 -540,9 +540,9 @@@ init_chown_advanced (void
      int i;
      enum { dlg_h = 13, dlg_w = 74, n_elem = 4 };
  #ifdef ENABLE_NLS
 -    static int i18n_len;
 -    
 -    if (!i18n_len) {
 +    static int i18n_len = 0;
 +
 +    if (i18n_len == 0) {
  	int dx, cx;
  	for (i = 0 ; i < n_elem ; i++) {
  	    chown_advanced_but[i].text = _(chown_advanced_but[i].text);
@@@ -596,7 -597,7 +597,7 @@@
  static void
  chown_advanced_done (void)
  {
-     g_free (sf_stat);
+     mhl_mem_free (sf_stat);
      if (need_update)
  	update_panels (UP_OPTIMIZE, UP_KEEPSEL);
      repaint_screen ();
diff --combined src/boxes.c
index 33ec10e,f3e6e05..173908d
--- a/src/boxes.c
+++ b/src/boxes.c
@@@ -30,7 -30,7 +30,8 @@@
  #include <sys/types.h>
  #include <sys/stat.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -198,7 -198,7 +199,7 @@@ display_init (int radio_sel, char *init
  
      status =
  	input_new (10, 9, INPUT_COLOR, DISPLAY_X - 14, _status[radio_sel],
 -		   "mini-input");
 +		   "mini-input", INPUT_COMPLETE_DEFAULT);
      add_widget (dd, status);
      input_set_point (status, 0);
  
@@@ -208,7 -208,7 +209,7 @@@
  
      user =
  	input_new (7, 9, INPUT_COLOR, DISPLAY_X - 14, init_text,
 -		   "user-fmt-input");
 +		   "user-fmt-input", INPUT_COMPLETE_DEFAULT);
      add_widget (dd, user);
      input_set_point (user, 0);
  
@@@ -228,17 -228,17 +229,17 @@@ display_box (WPanel *panel, char **user
          p = get_nth_panel_name (num);
          panel = g_new (WPanel, 1);
          panel->list_type = list_full;
 -        panel->user_format = g_strdup (DEFAULT_USER_FORMAT);
 +        panel->user_format = mhl_str_dup (DEFAULT_USER_FORMAT);
          panel->user_mini_status = 0;
  	for (i = 0; i < LIST_TYPES; i++)
 -    	    panel->user_status_format[i] = g_strdup (DEFAULT_USER_FORMAT);
 +    	    panel->user_status_format[i] = mhl_str_dup (DEFAULT_USER_FORMAT);
          section = g_strconcat ("Temporal:", p, (char *) NULL);
          if (!profile_has_section (section, profile_name)) {
-             g_free (section);
+             mhl_mem_free (section);
 -            section = g_strdup (p);
 +            section = mhl_str_dup (p);
          }
          panel_load_setup (panel, section);
-         g_free (section);
+         mhl_mem_free (section);
      }
  
      current_mode = panel->list_type;
@@@ -250,16 -250,16 +251,16 @@@
      result = -1;
      
      if (section) {
-         g_free (panel->user_format);
+         mhl_mem_free (panel->user_format);
  	for (i = 0; i < LIST_TYPES; i++)
- 	   g_free (panel->user_status_format [i]);
-         g_free (panel);
+ 	   mhl_mem_free (panel->user_status_format [i]);
+         mhl_mem_free (panel);
      }
      
      if (dd->ret_value != B_CANCEL){
  	result = my_radio->sel;
 -	*userp = g_strdup (user->buffer);
 -	*minip = g_strdup (status->buffer);
 +	*userp = mhl_str_dup (user->buffer);
 +	*minip = mhl_str_dup (status->buffer);
  	*use_msformat = check_status->state & C_BOOL;
      }
      destroy_dlg (dd);
@@@ -572,7 -572,7 +573,7 @@@ sel_charset_button (int action
  	: codepages[new_display_codepage].name;
  
      /* avoid strange bug with label repainting */
 -    g_snprintf (buf, sizeof (buf), "%-27s", cpname);
 +    snprintf (buf, sizeof (buf), "%-27s", cpname);
      label_set_text (cplabel, buf);
      return 0;
  }
@@@ -692,7 -692,7 +693,7 @@@ tree_box (const char *current_dir
      
      run_dlg (dlg);
      if (dlg->ret_value == B_ENTER)
 -	val = g_strdup (tree_selected_name (mytree));
 +	val = mhl_str_dup (tree_selected_name (mytree));
      else
  	val = 0;
      
@@@ -773,29 -773,29 +774,29 @@@ configure_vfs (void
      ret_use_netrc = use_netrc;
      ret_ftpfs_use_passive_connections = ftpfs_use_passive_connections;
      ret_ftpfs_use_passive_connections_over_proxy = ftpfs_use_passive_connections_over_proxy;
 -    g_snprintf(buffer3, sizeof (buffer3), "%i", ftpfs_directory_timeout);
 +    snprintf(buffer3, sizeof (buffer3), "%i", ftpfs_directory_timeout);
      confvfs_widgets[8].text = buffer3;
      confvfs_widgets[10].text = ftpfs_anonymous_passwd;
      confvfs_widgets[5].text = ftpfs_proxy_host;
  #endif
 -    g_snprintf (buffer2, sizeof (buffer2), "%i", vfs_timeout);
 +    snprintf (buffer2, sizeof (buffer2), "%i", vfs_timeout);
      confvfs_widgets [3 + VFS_WIDGETBASE].text = buffer2;
  
      if (quick_dialog (&confvfs_dlg) != B_CANCEL) {
          vfs_timeout = atoi (ret_timeout);
-         g_free (ret_timeout);
+         mhl_mem_free (ret_timeout);
          if (vfs_timeout < 0 || vfs_timeout > 10000)
              vfs_timeout = 10;
  #if defined(USE_NETCODE)
- 	g_free (ftpfs_anonymous_passwd);
+ 	mhl_mem_free (ftpfs_anonymous_passwd);
  	ftpfs_anonymous_passwd = ret_passwd;
- 	g_free (ftpfs_proxy_host);
+ 	mhl_mem_free (ftpfs_proxy_host);
  	ftpfs_proxy_host = ret_ftp_proxy;
  	ftpfs_directory_timeout = atoi(ret_directory_timeout);
  	use_netrc = ret_use_netrc;
  	ftpfs_use_passive_connections = ret_ftpfs_use_passive_connections;
  	ftpfs_use_passive_connections_over_proxy = ret_ftpfs_use_passive_connections_over_proxy;
- 	g_free (ret_directory_timeout);
+ 	mhl_mem_free (ret_directory_timeout);
  #endif
      }
  }
@@@ -906,7 -906,7 +907,7 @@@ jobs_fill_listbox (void
  
  	s = g_strconcat (state_str [tl->state], " ", tl->info, (char *) NULL);
  	listbox_add_item (bg_list, LISTBOX_APPEND_AT_END, 0, s, (void *) tl);
- 	g_free (s);
+ 	mhl_mem_free (s);
  	tl = tl->next;
      }
  }
@@@ -1084,19 -1084,19 +1085,19 @@@ vfs_smb_get_authinfo (const char *host
      auth_dlg = create_dlg (0, 0, dialog_y, dialog_x, dialog_colors, NULL,
  			   "[Smb Authinfo]", title, DLG_CENTER | DLG_REVERSE);
  
-     g_free (title);
+     mhl_mem_free (title);
  
 -    in_user  = input_new (5, istart, INPUT_COLOR, ilen, user, "auth_name");
 +    in_user  = input_new (5, istart, INPUT_COLOR, ilen, user, "auth_name", INPUT_COMPLETE_DEFAULT);
      add_widget (auth_dlg, in_user);
  
 -    in_domain = input_new (3, istart, INPUT_COLOR, ilen, domain, "auth_domain");
 +    in_domain = input_new (3, istart, INPUT_COLOR, ilen, domain, "auth_domain", INPUT_COMPLETE_DEFAULT);
      add_widget (auth_dlg, in_domain);
      add_widget (auth_dlg, button_new (9, b2, B_CANCEL, NORMAL_BUTTON,
                   buts[1], 0));
      add_widget (auth_dlg, button_new (9, b0, B_ENTER, DEFPUSH_BUTTON,
                   buts[0], 0));
  
 -    in_password  = input_new (7, istart, INPUT_COLOR, ilen, "", "auth_password");
 +    in_password  = input_new (7, istart, INPUT_COLOR, ilen, "", "auth_password", INPUT_COMPLETE_DEFAULT);
      in_password->completion_flags = 0;
      in_password->is_password = 1;
      add_widget (auth_dlg, in_password);
@@@ -1114,11 -1114,11 +1115,11 @@@
      default:
          return_value = g_new (struct smb_authinfo, 1);
          if (return_value) {
 -            return_value->host = g_strdup (host);
 -            return_value->share = g_strdup (share);
 -            return_value->domain = g_strdup (in_domain->buffer);
 -            return_value->user = g_strdup (in_user->buffer);
 -            return_value->password = g_strdup (in_password->buffer);
 +            return_value->host = mhl_str_dup (host);
 +            return_value->share = mhl_str_dup (share);
 +            return_value->domain = mhl_str_dup (in_domain->buffer);
 +            return_value->user = mhl_str_dup (in_user->buffer);
 +            return_value->password = mhl_str_dup (in_password->buffer);
          }
      }
  
diff --combined src/charsets.c
index cb45a52,42989a3..2b0c05a
--- a/src/charsets.c
+++ b/src/charsets.c
@@@ -27,8 -27,6 +27,8 @@@
  
  #include <iconv.h>
  
 +#include <mhl/string.h>
 +
  #include "global.h"
  #include "charsets.h"
  
@@@ -50,13 -48,13 +50,13 @@@ load_codepages_list (void
      extern int display_codepage;
      char *default_codepage = NULL;
  
 -    fname = concat_dir_and_file (mc_home, CHARSETS_INDEX);
 +    fname = mhl_str_dir_plus_file (mc_home, CHARSETS_INDEX);
      if (!(f = fopen (fname, "r"))) {
  	fprintf (stderr, _("Warning: file %s not found\n"), fname);
- 	g_free (fname);
+ 	mhl_mem_free (fname);
  	return -1;
      }
-     g_free (fname);
+     mhl_mem_free (fname);
  
      for (n_codepages = 0; fgets (buf, sizeof (buf), f);)
  	if (buf[0] != '\n' && buf[0] != '\0' && buf[0] != '#')
@@@ -88,18 -86,18 +88,18 @@@
  	    goto fail;
  
  	if (strcmp (buf, "default") == 0) {
 -	    default_codepage = g_strdup (p);
 +	    default_codepage = mhl_str_dup (p);
  	    continue;
  	}
  
 -	codepages[n_codepages].id = g_strdup (buf);
 -	codepages[n_codepages].name = g_strdup (p);
 +	codepages[n_codepages].id = mhl_str_dup (buf);
 +	codepages[n_codepages].name = mhl_str_dup (p);
  	++n_codepages;
      }
  
      if (default_codepage) {
  	display_codepage = get_codepage_index (default_codepage);
- 	g_free (default_codepage);
+ 	mhl_mem_free (default_codepage);
      }
  
      result = n_codepages;
@@@ -114,11 -112,11 +114,11 @@@ free_codepages_list (void
      if (n_codepages > 0) {
  	int i;
  	for (i = 0; i < n_codepages; i++) {
- 	    g_free (codepages[i].id);
- 	    g_free (codepages[i].name);
+ 	    mhl_mem_free (codepages[i].id);
+ 	    mhl_mem_free (codepages[i].name);
  	}
  	n_codepages = 0;
- 	g_free (codepages);
+ 	mhl_mem_free (codepages);
  	codepages = 0;
      }
  }
@@@ -198,7 -196,7 +198,7 @@@ init_translation_table (int cpsource, i
  
      cd = iconv_open (cpdisp, cpsour);
      if (cd == (iconv_t) - 1) {
 -	g_snprintf (errbuf, sizeof (errbuf),
 +	snprintf (errbuf, sizeof (errbuf),
  		    _("Cannot translate from %s to %s"), cpsour, cpdisp);
  	return errbuf;
      }
@@@ -212,7 -210,7 +212,7 @@@
  
      cd = iconv_open (cpsour, cpdisp);
      if (cd == (iconv_t) - 1) {
 -	g_snprintf (errbuf, sizeof (errbuf),
 +	snprintf (errbuf, sizeof (errbuf),
  		    _("Cannot translate from %s to %s"), cpdisp, cpsour);
  	return errbuf;
      }
diff --combined src/cmd.c
index e4b934f,c31433f..373cacc
--- a/src/cmd.c
+++ b/src/cmd.c
@@@ -33,7 -33,7 +33,8 @@@
  #endif
  #include <unistd.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "cmd.h"		/* Our definitions */
@@@ -120,7 -120,7 +121,7 @@@ view_file_at_line (const char *filename
  	char view_entry[BUF_TINY];
  
  	if (start_line != 0)
 -	    g_snprintf (view_entry, sizeof (view_entry), "View:%d",
 +	    snprintf (view_entry, sizeof (view_entry), "View:%d",
  			start_line);
  	else
  	    strcpy (view_entry, "View");
@@@ -240,7 -240,7 +241,7 @@@ view_file_cmd (void
  	return;
  
      view_file (filename, 0, use_internal_view);
-     g_free (filename);
+     mhl_mem_free (filename);
  }
  
  /* Run plain internal viewer on the currently selected file */
@@@ -265,7 -265,7 +266,7 @@@ filtered_view_cmd (void
  
      mc_internal_viewer (command, "", NULL, 0);
  
-     g_free (command);
+     mhl_mem_free (command);
  }
  
  void do_edit_at_line (const char *what, int start_line)
@@@ -370,9 -370,9 +371,9 @@@ mkdir_cmd (void
  	return;
  
      if (dir[0] == '/' || dir[0] == '~')
 -	absdir = g_strdup (dir);
 +	absdir = mhl_str_dup (dir);
      else
 -	absdir = concat_dir_and_file (current_panel->cwd, dir);
 +	absdir = mhl_str_dir_plus_file (current_panel->cwd, dir);
  
      save_cwds_stat ();
      if (my_mkdir (absdir, 0777) == 0) {
@@@ -383,8 -383,8 +384,8 @@@
  	message (D_ERROR, MSG_ERROR, "  %s  ", unix_error_string (errno));
      }
  
-     g_free (absdir);
-     g_free (dir);
+     mhl_mem_free (absdir);
+     mhl_mem_free (dir);
  }
  
  void delete_cmd (void)
@@@ -416,13 -416,13 +417,13 @@@ void find_cmd (void
  static void
  set_panel_filter_to (WPanel *p, char *allocated_filter_string)
  {
-     g_free (p->filter);
+     mhl_mem_free (p->filter);
      p->filter = 0;
  
      if (!(allocated_filter_string [0] == '*' && allocated_filter_string [1] == 0))
  	p->filter = allocated_filter_string;
      else
- 	g_free (allocated_filter_string);
+ 	mhl_mem_free (allocated_filter_string);
      reread_cmd ();
  }
  
@@@ -494,7 -494,7 +495,7 @@@ select_unselect_cmd (const char *title
      if (!reg_exp)
  	return;
      if (!*reg_exp) {
- 	g_free (reg_exp);
+ 	mhl_mem_free (reg_exp);
  	return;
      }
  
@@@ -524,14 -524,14 +525,14 @@@
  			  match_file);
  	if (c == -1) {
  	    message (D_ERROR, MSG_ERROR, _("  Malformed regular expression  "));
- 	    g_free (reg_exp);
+ 	    mhl_mem_free (reg_exp);
  	    return;
  	}
  	if (c) {
  	    do_file_mark (current_panel, i, cmd);
  	}
      }
-     g_free (reg_exp);
+     mhl_mem_free (reg_exp);
  }
  
  void select_cmd (void)
@@@ -578,17 -578,17 +579,17 @@@ void ext_cmd (void
  			    _(" Which extension file you want to edit? "), D_NORMAL, 2,
  			    _("&User"), _("&System Wide"));
      }
 -    extdir = concat_dir_and_file (mc_home, MC_LIB_EXT);
 +    extdir = mhl_str_dir_plus_file (mc_home, MC_LIB_EXT);
  
      if (dir == 0){
 -	buffer = concat_dir_and_file (home_dir, MC_USER_EXT);
 +	buffer = mhl_str_dir_plus_file (home_dir, MC_USER_EXT);
  	check_for_default (extdir, buffer);
  	do_edit (buffer);
- 	g_free (buffer);
+ 	mhl_mem_free (buffer);
      } else if (dir == 1)
  	do_edit (extdir);
  
-    g_free (extdir);
+    mhl_mem_free (extdir);
     flush_extension_file ();
  }
  
@@@ -608,32 -608,32 +609,32 @@@ menu_edit_cmd (int where
  	_("&Local"), _("&User"), _("&System Wide")
      );
  
 -    menufile = concat_dir_and_file (mc_home, where ? CEDIT_GLOBAL_MENU : MC_GLOBAL_MENU);
 +    menufile = mhl_str_dir_plus_file (mc_home, where ? CEDIT_GLOBAL_MENU : MC_GLOBAL_MENU);
  
      switch (dir) {
  	case 0:
 -	    buffer = g_strdup (where ? CEDIT_LOCAL_MENU : MC_LOCAL_MENU);
 +	    buffer = mhl_str_dup (where ? CEDIT_LOCAL_MENU : MC_LOCAL_MENU);
  	    check_for_default (menufile, buffer);
  	    break;
  
  	case 1:
 -	    buffer = concat_dir_and_file (home_dir, where ? CEDIT_HOME_MENU : MC_HOME_MENU);
 +	    buffer = mhl_str_dir_plus_file (home_dir, where ? CEDIT_HOME_MENU : MC_HOME_MENU);
  	    check_for_default (menufile, buffer);
  	    break;
  	
  	case 2:
 -	    buffer = concat_dir_and_file (mc_home, where ? CEDIT_GLOBAL_MENU : MC_GLOBAL_MENU);
 +	    buffer = mhl_str_dir_plus_file (mc_home, where ? CEDIT_GLOBAL_MENU : MC_GLOBAL_MENU);
  	    break;
  
  	default:
- 	   g_free (menufile);
+ 	   mhl_mem_free (menufile);
  	    return;
      }
      do_edit (buffer);
  	if (dir == 0)
  		chmod(buffer, 0600);
-     g_free (buffer);
-     g_free (menufile);
+     mhl_mem_free (buffer);
+     mhl_mem_free (menufile);
  }
  
  void quick_chdir_cmd (void)
@@@ -649,7 -649,7 +650,7 @@@
      else
          if (!do_cd (target, cd_exact))
  	    message (D_ERROR, MSG_ERROR, _("Cannot change directory") );
-     g_free (target);
+     mhl_mem_free (target);
  }
  
  /* edit file menu for mc */
@@@ -681,17 -681,17 +682,17 @@@ edit_syntax_cmd (void
  			  _(" Which syntax file you want to edit? "), D_NORMAL, 2,
  			  _("&User"), _("&System Wide"));
      }
 -    extdir = concat_dir_and_file (mc_home, "syntax" PATH_SEP_STR "Syntax");
 +    extdir = mhl_str_dir_plus_file (mc_home, "syntax" PATH_SEP_STR "Syntax");
  
      if (dir == 0) {
 -	buffer = concat_dir_and_file (home_dir, SYNTAX_FILE);
 +	buffer = mhl_str_dir_plus_file (home_dir, SYNTAX_FILE);
  	check_for_default (extdir, buffer);
  	do_edit (buffer);
- 	g_free (buffer);
+ 	mhl_mem_free (buffer);
      } else if (dir == 1)
  	do_edit (extdir);
  
-     g_free (extdir);
+     mhl_mem_free (extdir);
  }
  #endif
  
@@@ -706,7 -706,7 +707,7 @@@ void reselect_vfs (void
  
      if (!do_cd (target, cd_exact))
          message (D_ERROR, MSG_ERROR, _("Cannot change directory") );
-     g_free (target);
+     mhl_mem_free (target);
  }
  #endif /* USE_VFS */
  
@@@ -815,12 -815,12 +816,12 @@@ compare_dir (WPanel *panel, WPanel *oth
  	    }
  
  	    /* Thorough compare on, do byte-by-byte comparison */
 -	    src_name = concat_dir_and_file (panel->cwd, source->fname);
 -	    dst_name = concat_dir_and_file (other->cwd, target->fname);
 +	    src_name = mhl_str_dir_plus_file (panel->cwd, source->fname);
 +	    dst_name = mhl_str_dir_plus_file (other->cwd, target->fname);
  	    if (compare_files (src_name, dst_name, source->st.st_size))
  		do_file_mark (panel, i, 1);
- 	    g_free (src_name);
- 	    g_free (dst_name);
+ 	    mhl_mem_free (src_name);
+ 	    mhl_mem_free (dst_name);
  	}
      } /* for (i ...) */
  }
@@@ -879,7 -879,7 +880,7 @@@ history_cmd (void
      else
  	current = listbox->list->current->data;
      destroy_dlg (listbox->dlg);
-     g_free (listbox);
+     mhl_mem_free (listbox);
  
      if (!current)
  	return;
@@@ -930,17 -930,17 +931,17 @@@ do_link (int symbolic_link, const char 
  	char *d;
  
  	/* suggest the full path for symlink */
 -	s = concat_dir_and_file (current_panel->cwd, fname);
 +	s = mhl_str_dir_plus_file (current_panel->cwd, fname);
  
  	if (get_other_type () == view_listing) {
 -	    d = concat_dir_and_file (other_panel->cwd, fname);
 +	    d = mhl_str_dir_plus_file (other_panel->cwd, fname);
  	} else {
 -	    d = g_strdup (fname);
 +	    d = mhl_str_dup (fname);
  	}
  
  	symlink_dialog (s, d, &dest, &src);
- 	g_free (d);
- 	g_free (s);
+ 	mhl_mem_free (d);
+ 	mhl_mem_free (s);
  
  	if (!dest || !*dest || !src || !*src)
  	    goto cleanup;
@@@ -953,8 -953,8 +954,8 @@@
      repaint_screen ();
  
  cleanup:
-     g_free (src);
-     g_free (dest);
+     mhl_mem_free (src);
+     mhl_mem_free (dest);
  }
  
  void link_cmd (void)
@@@ -1002,10 -1002,10 +1003,10 @@@ void edit_symlink_cmd (void
  		    update_panels (UP_OPTIMIZE, UP_KEEPSEL);
  		    repaint_screen ();
  		}
- 		g_free (dest);
+ 		mhl_mem_free (dest);
  	    }
  	}
- 	g_free (q);
+ 	mhl_mem_free (q);
      } else {
  	message (D_ERROR, MSG_ERROR, _("`%s' is not a symbolic link"),
  		 selection (current_panel)->fname);
@@@ -1024,7 -1024,7 +1025,7 @@@ user_file_menu_cmd (void
  }
  
  /* partly taken from dcigettext.c, returns "" for default locale */
- /* value should be freed by calling function g_free() */
+ /* value should be freed by calling function mhl_mem_free() */
  char *guess_message_value (void)
  {
      static const char * const var[] = {
@@@ -1054,7 -1054,7 +1055,7 @@@
      if (locale == NULL)
  	locale = "";
  
 -    return g_strdup (locale);
 +    return mhl_str_dup (locale);
  }
  
  /*
@@@ -1072,7 -1072,7 +1073,7 @@@ get_random_hint (int force
      /* Do not change hints more often than one minute */
      gettimeofday (&tv, NULL);
      if (!force && !(tv.tv_sec > last_sec + 60))
 -	return g_strdup ("");
 +	return mhl_str_dup ("");
      last_sec = tv.tv_sec;
  
      data = load_mc_home_file (MC_HINT, NULL);
@@@ -1093,8 -1093,8 +1094,8 @@@
      eol = strchr (&data[start], '\n');
      if (eol)
  	*eol = 0;
 -    result = g_strdup (&data[start]);
 +    result = mhl_str_dup (&data[start]);
-     g_free (data);
+     mhl_mem_free (data);
      return result;
  }
  
@@@ -1125,8 -1125,8 +1126,8 @@@ nice_cd (const char *text, const char *
  	directory_history_add (MENU_PANEL, (MENU_PANEL)->cwd);
      else
  	message (D_ERROR, MSG_ERROR, _(" Cannot chdir to %s "), cd_path);
-     g_free (cd_path);
-     g_free (machine);
+     mhl_mem_free (cd_path);
+     mhl_mem_free (machine);
  }
  #endif /* USE_NETCODE || USE_EXT2FSLIB */
  
@@@ -1186,9 -1186,9 +1187,9 @@@ void quick_cd_cmd (void
          char *q = g_strconcat ("cd ", p, (char *) NULL);
          
          do_cd_command (q);
-         g_free (q);
+         mhl_mem_free (q);
      }
-     g_free (p);
+     mhl_mem_free (p);
  }
  
  void
@@@ -1254,17 -1254,17 +1255,17 @@@ configure_panel_listing (WPanel *p, in
      p->list_type = view_type;
      
      if (view_type == list_user || use_msformat){
- 	g_free (p->user_format);
+ 	mhl_mem_free (p->user_format);
  	p->user_format = user;
      
- 	g_free (p->user_status_format [view_type]);
+ 	mhl_mem_free (p->user_status_format [view_type]);
  	p->user_status_format [view_type] = status;
      
  	set_panel_formats (p);
      }
      else {
-         g_free (user);
-         g_free (status);
+         mhl_mem_free (user);
+         mhl_mem_free (status);
      }
  
      set_panel_formats (p);
diff --combined src/color.c
index 96059c6,aac92a9..a98b588
--- a/src/color.c
+++ b/src/color.c
@@@ -22,7 -22,7 +22,8 @@@
  #include <stdlib.h>
  #include <string.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -228,7 -228,7 +229,7 @@@ static void configure_colors_string (co
      if (!the_color_string)
  	return;
  
 -    p = color_string = g_strdup (the_color_string);
 +    p = color_string = mhl_str_dup (the_color_string);
      while (color_string && *color_string){
  	while (*color_string == ' ' || *color_string == '\t')
  	    color_string++;
@@@ -254,7 -254,7 +255,7 @@@
  			color_string++;
  	}
      }
-    g_free (p);
+    mhl_mem_free (p);
  }
  
  static void configure_colors (void)
@@@ -397,8 -397,8 +398,8 @@@ try_alloc_color_pair (const char *fg, c
      p->next = g_new (struct colors_avail, 1);
      p = p->next;
      p->next = 0;
 -    p->fg = fg ? g_strdup (fg) : 0;
 -    p->bg = bg ? g_strdup (bg) : 0;
 +    p->fg = fg ? mhl_str_dup (fg) : 0;
 +    p->bg = bg ? mhl_str_dup (bg) : 0;
      if (!fg)
          /* Index in color_map array = COLOR_INDEX - 1 */
  	fg = color_map[EDITOR_NORMAL_COLOR_INDEX - 1].fg;
@@@ -436,8 -436,8 +437,8 @@@ try_alloc_color_pair (const char *fg, c
      p->next = g_new (struct colors_avail, 1);
      p = p->next;
      p->next = 0;
 -    p->fg = fg ? g_strdup (fg) : 0;
 -    p->bg = bg ? g_strdup (bg) : 0;
 +    p->fg = fg ? mhl_str_dup (fg) : 0;
 +    p->bg = bg ? mhl_str_dup (bg) : 0;
      if (!fg)
          /* Index in color_map array = COLOR_INDEX - 1 */
  	fg_index = color_map[EDITOR_NORMAL_COLOR_INDEX - 1].fg;
@@@ -466,9 -466,9 +467,9 @@@ done_colors (void
  
      for (p = c.next; p; p = next) {
  	next = p->next;
- 	g_free (p->fg);
- 	g_free (p->bg);
- 	g_free (p);
+ 	mhl_mem_free (p->fg);
+ 	mhl_mem_free (p->bg);
+ 	mhl_mem_free (p);
      }
      c.next = NULL;
  }
diff --combined src/command.c
index 644a35c,a1e5f69..536c14d
--- a/src/command.c
+++ b/src/command.c
@@@ -28,13 -28,12 +28,13 @@@
  #include <string.h>
  
  #include <mhl/memory.h>
- #include <mhl/escape.h>
 +#include <mhl/string.h>
++#include <mhl/escape.h>
  
  #include "global.h"		/* home_dir */
  #include "tty.h"
  #include "widget.h"		/* WInput */
  #include "command.h"
 -#include "complete.h"		/* completion constants */
  #include "wtools.h"		/* message () */
  #include "panel.h"		/* view_tree enum. Also, needed by main.h */
  #include "main.h"		/* do_cd */
@@@ -67,7 -66,6 +67,7 @@@ examine_cd (char *path
      const char *t;
  
      /* Tilde expansion */
 +    path = mhl_shell_unescape_buf(path);
      path_tilde = tilde_expand (path);
  
      /* Leave space for further expansion */
@@@ -115,7 -113,7 +115,7 @@@
  
      /* CDPATH handling */
      if (*q != PATH_SEP && !result) {
 -	char * const cdpath = g_strdup (getenv ("CDPATH"));
 +	char * const cdpath = mhl_str_dup (getenv ("CDPATH"));
  	char *p = cdpath;
  	if (p == NULL)
  	    c = 0;
@@@ -128,18 -126,17 +128,17 @@@
  	    c = *s;
  	    *s = 0;
  	    if (*p) {
 -		r = concat_dir_and_file (p, q);
 +		r = mhl_str_dir_plus_file (p, q);
  		result = do_cd (r, cd_parse_command);
- 		g_free (r);
+ 		mhl_mem_free (r);
  	    }
  	    *s = c;
  	    p = s + 1;
  	}
- 	g_free (cdpath);
+ 	mhl_mem_free (cdpath);
      }
-     g_free (q);
-     g_free (path_tilde);
- //    mhl_mem_free(path);
+     mhl_mem_free (q);
+     mhl_mem_free (path_tilde);
      return result;
  }
  
@@@ -181,16 -178,16 +180,16 @@@ void do_cd_command (char *cmd
  	} else {
  	    char *old = current_panel->cwd;
  	    char *new;
 -	    new = concat_dir_and_file (old, cmd+3);
 +	    new = mhl_str_dir_plus_file (old, cmd+3);
  	    sync_tree (new);
- 	    g_free (new);
+ 	    mhl_mem_free (new);
  	}
      } else
  	if (!examine_cd (&cmd [3])) {
 -	    char *d = strip_password (g_strdup (&cmd [3]), 1);
 +	    char *d = strip_password (mhl_str_dup (&cmd [3]), 1);
  	    message (D_ERROR, MSG_ERROR, _(" Cannot chdir to \"%s\" \n %s "),
  		     d, unix_error_string (errno));
- 	    g_free (d);
+ 	    mhl_mem_free (d);
  	    return;
  	}
  }
@@@ -244,7 -241,7 +243,7 @@@ enter (WInput *cmdline
  		s = expand_format (NULL, cmd[i], 1);
  		command = g_realloc (command, j + strlen (s) + cmd_len - i + 1);
  		strcpy (command + j, s);
- 		g_free (s);
+ 		mhl_mem_free (s);
  		j = strlen (command);
  	    } else {
  		command[j] = cmd[i];
@@@ -254,7 -251,7 +253,7 @@@
  	}
  	new_input (cmdline);
  	shell_execute (command, 0);
- 	g_free (command);
+ 	mhl_mem_free (command);
  
  #ifdef HAVE_SUBSHELL_SUPPORT
  	if (quit & SUBSHELL_EXIT) {
@@@ -295,8 -292,7 +294,8 @@@ command_new (int y, int x, int cols
  {
      WInput *cmd;
  
 -    cmd = input_new (y, x, DEFAULT_COLOR, cols, "", "cmdline");
 +    cmd = input_new (y, x, DEFAULT_COLOR, cols, "", "cmdline",
 +	INPUT_COMPLETE_DEFAULT | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS | INPUT_COMPLETE_SHELL_ESC);
  
      /* Add our hooks */
      cmd->widget.callback = command_callback;
@@@ -316,6 -312,6 +315,6 @@@ command_insert (WInput * in, const cha
  
      quoted_text = name_quote (text, 1);
      stuff (in, quoted_text, insert_extra_space);
-     g_free (quoted_text);
+     mhl_mem_free (quoted_text);
  }
  
diff --combined src/complete.c
index d8c7f07,6ddd7bf..2c483d2
--- a/src/complete.c
+++ b/src/complete.c
@@@ -31,8 -31,6 +31,8 @@@
  #include <unistd.h>
  
  #include <mhl/memory.h>
 +#include <mhl/escape.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -41,38 -39,21 +41,38 @@@
  #include "dialog.h"
  #include "widget.h"
  #include "wtools.h"
 -#include "complete.h"
  #include "main.h"
 +#include "util.h"
  #include "key.h"		/* XCTRL and ALT macros */
  
 -typedef char *CompletionFunction (char *, int);
 +typedef char *CompletionFunction (char * text, int state, INPUT_COMPLETE_FLAGS flags);
  
 -/* This flag is used in filename_completion_function */
 -static int ignore_filenames = 0;
 +//#define DO_COMPLETION_DEBUG
 +#ifdef DO_COMPLETION_DEBUG
 +/*
 + * Useful to print/debug completion flags
 + */
 +static const char * show_c_flags(INPUT_COMPLETE_FLAGS flags)
 +{
 +    static char s_cf[] = "FHCVUDS";
  
 -/* This flag is used by command_completion_function */
 -/* to hint the filename_completion_function */
 -static int look_for_executables = 0;
 +    s_cf[0] = (flags & INPUT_COMPLETE_FILENAMES) ? 'F' : ' ';
 +    s_cf[1] = (flags & INPUT_COMPLETE_HOSTNAMES) ? 'H' : ' ';
 +    s_cf[2] = (flags & INPUT_COMPLETE_COMMANDS)  ? 'C' : ' ';
 +    s_cf[3] = (flags & INPUT_COMPLETE_VARIABLES) ? 'V' : ' ';
 +    s_cf[4] = (flags & INPUT_COMPLETE_USERNAMES) ? 'U' : ' ';
 +    s_cf[5] = (flags & INPUT_COMPLETE_CD)        ? 'D' : ' ';
 +    s_cf[6] = (flags & INPUT_COMPLETE_SHELL_ESC) ? 'S' : ' ';
 +
 +    return s_cf;
 +}
 +#define SHOW_C_CTX(func) fprintf(stderr, "%s: text='%s' flags=%s\n", func, text, show_c_flags(flags))
 +#else
 +#define SHOW_C_CTX(func)
 +#endif /* DO_CMPLETION_DEBUG */
  
  static char *
 -filename_completion_function (char *text, int state)
 +filename_completion_function (char *text, int state, INPUT_COMPLETE_FLAGS flags)
  {
      static DIR *directory;
      static char *filename = NULL;
@@@ -83,25 -64,20 +83,25 @@@
  
      struct dirent *entry = NULL;
  
 +    SHOW_C_CTX("filename_completion_function");
 +
 +    if (text && (flags & INPUT_COMPLETE_SHELL_ESC))
 +        text = mhl_shell_unescape_buf (text);
 +
      /* If we're starting the match process, initialize us a bit. */
      if (!state){
          const char *temp;
  
-         g_free (dirname);
-         g_free (filename);
-         g_free (users_dirname);
+         mhl_mem_free (dirname);
+         mhl_mem_free (filename);
+         mhl_mem_free (users_dirname);
  
  	if ((*text) && (temp = strrchr (text, PATH_SEP))){
 -	    filename = g_strdup (++temp);
 +	    filename = mhl_str_dup (++temp);
  	    dirname = g_strndup (text, temp - text);
  	} else {
 -	    dirname = g_strdup (".");
 -	    filename = g_strdup (text);
 +	    dirname = mhl_str_dup (".");
 +	    filename = mhl_str_dup (text);
  	}
  
          /* We aren't done yet.  We also support the "~user" syntax. */
@@@ -109,7 -85,6 +109,7 @@@
          /* Save the version of the directory that the user typed. */
          users_dirname = dirname;
          {
 +	    // FIXME: memleak ?
  	    dirname = tilde_expand (dirname);
  	    canonicalize_pathname (dirname);
  	    /* Here we should do something with variable expansion
@@@ -159,17 -134,20 +159,17 @@@
  	                isexec = 1;
  	        }
  	    }
- 	   g_free (tmp);
+ 	   mhl_mem_free (tmp);
  	}
 -	switch (look_for_executables)
 -	{
 -	    case 2: if (!isexec)
 -	    	        continue;
 -	    	    break;
 -	    case 1: if (!isexec && !isdir)
 -	    	        continue;
 -	    	    break;
 -	}
 -	if (ignore_filenames && !isdir)
 -	    continue;
 -	break;
 +	if ((flags & INPUT_COMPLETE_COMMANDS)
 +	    && (isexec || isdir))
 +	    break;
 +	if ((flags & INPUT_COMPLETE_CD)
 +	    && isdir)
 +	    break;
 +	if (flags & (INPUT_COMPLETE_FILENAMES))
 +	    break;
 +	continue;
      }
  
      if (!entry){
@@@ -177,11 -155,11 +177,11 @@@
  	    mc_closedir (directory);
  	    directory = NULL;
  	}
- 	g_free (dirname);
+ 	mhl_mem_free (dirname);
  	dirname = NULL;
- 	g_free (filename);
+ 	mhl_mem_free (filename);
  	filename = NULL;
- 	g_free (users_dirname);
+ 	mhl_mem_free (users_dirname);
  	users_dirname = NULL;
          return NULL;
      } else {
@@@ -203,28 -181,18 +203,28 @@@
  	}
  	if (isdir)
  	    strcat (temp, PATH_SEP_STR);
 -        return temp;
 +
 +	if (temp && (flags & INPUT_COMPLETE_SHELL_ESC))
 +	{
 +	    SHELL_ESCAPED_STR e_temp = mhl_shell_escape_dup(temp);
 +	    mhl_mem_free (temp);
 +	    temp = e_temp.s;
 +	}
 +	return temp;
      }
  }
  
  /* We assume here that text[0] == '~' , if you want to call it in another way,
     you have to change the code */
  static char *
 -username_completion_function (char *text, int state)
 +username_completion_function (char *text, int state, INPUT_COMPLETE_FLAGS flags)
  {
      static struct passwd *entry;
      static int userlen;
  
 +    SHOW_C_CTX("username_completion_function");
 +
 +    if (text[0] == '\\' && text[1] == '~') text++;
      if (!state){ /* Initialization stuff */
          setpwent ();
          userlen = strlen (text + 1);
@@@ -259,14 -227,12 +259,14 @@@ extern char **environ
  /* We assume text [0] == '$' and want to have a look at text [1], if it is
     equal to '{', so that we should append '}' at the end */
  static char *
 -variable_completion_function (char *text, int state)
 +variable_completion_function (char *text, int state, INPUT_COMPLETE_FLAGS flags)
  {
      static char **env_p;
      static int varlen, isbrace;
      const char *p = NULL;
  
 +    SHOW_C_CTX("variable_completion_function");
 +
      if (!state){ /* Initialization stuff */
  	isbrace = (text [1] == '{');
          varlen = strlen (text + 1 + isbrace);
@@@ -368,7 -334,7 +368,7 @@@ static void fetch_hosts (const char *fi
  	            *(hosts_p++) = name;
  	            *hosts_p = NULL;
  	        } else
- 	            g_free (name);
+ 	            mhl_mem_free (name);
  	    }
  	}
      }
@@@ -376,20 -342,18 +376,20 @@@
  }
  
  static char *
 -hostname_completion_function (char *text, int state)
 +hostname_completion_function (char *text, int state, INPUT_COMPLETE_FLAGS flags)
  {
      static char **host_p;
      static int textstart, textlen;
  
 +    SHOW_C_CTX("hostname_completion_function");
 +
      if (!state){ /* Initialization stuff */
          const char *p;
          
      	if (hosts != NULL){
      	    for (host_p = hosts; *host_p; host_p++)
-     	    	g_free (*host_p);
-     	   g_free (hosts);
+     	    	mhl_mem_free (*host_p);
+     	   mhl_mem_free (hosts);
      	}
      	hosts = g_new (char *, (hosts_alloclen = 30) + 1);
      	*hosts = NULL;
@@@ -410,8 -374,8 +410,8 @@@
      
      if (!*host_p){
      	for (host_p = hosts; *host_p; host_p++)
-     	    g_free (*host_p);
-     	g_free (hosts);
+     	    mhl_mem_free (*host_p);
+     	mhl_mem_free (hosts);
      	hosts = NULL;
      	return NULL;
      } else {
@@@ -432,7 -396,7 +432,7 @@@
   * table of shell built-ins.
   */
  static char *
 -command_completion_function (char *text, int state)
 +command_completion_function (char *text, int state, INPUT_COMPLETE_FLAGS flags)
  {
      static const char *path_end;
      static int isabsolute;
@@@ -458,21 -422,14 +458,21 @@@
      };
      char *p, *found;
  
 +    SHOW_C_CTX("command_completion_function");
 +
 +    if (!(flags & INPUT_COMPLETE_COMMANDS))
 +        return 0;
 +
 +    text = mhl_shell_unescape_buf(text);
 +    flags &= ~INPUT_COMPLETE_SHELL_ESC;
 +
      if (!state) {		/* Initialize us a little bit */
  	isabsolute = strchr (text, PATH_SEP) != 0;
 -	look_for_executables = isabsolute ? 1 : 2;
  	if (!isabsolute) {
  	    words = bash_reserved;
  	    phase = 0;
  	    text_len = strlen (text);
 -	    if (!path && (path = g_strdup (getenv ("PATH"))) != NULL) {
 +	    if (!path && (path = mhl_str_dup (getenv ("PATH"))) != NULL) {
  		p = path;
  		path_end = strchr (p, 0);
  		while ((p = strchr (p, PATH_ENV_SEP))) {
@@@ -483,12 -440,10 +483,12 @@@
      }
  
      if (isabsolute) {
 -	p = filename_completion_function (text, state);
 +	p = filename_completion_function (text, state, flags);
  	if (!p)
 -	    look_for_executables = 0;
 -	return p;
 +	    return 0;
 +	SHELL_ESCAPED_STR e_p = mhl_shell_escape_dup(p);
 +	mhl_mem_free(p);
 +	return e_p.s;
      }
  
      found = NULL;
@@@ -496,7 -451,7 +496,7 @@@
      case 0:			/* Reserved words */
  	while (*words) {
  	    if (!strncmp (*words, text, text_len))
 -		return g_strdup (*(words++));
 +		return mhl_str_dup (*(words++));
  	    words++;
  	}
  	phase++;
@@@ -504,7 -459,7 +504,7 @@@
      case 1:			/* Builtin commands */
  	while (*words) {
  	    if (!strncmp (*words, text, text_len))
 -		return g_strdup (*(words++));
 +		return mhl_str_dup (*(words++));
  	    words++;
  	}
  	phase++;
@@@ -520,33 -475,33 +520,32 @@@
  		if (cur_path >= path_end)
  		    break;
  		expanded = tilde_expand (*cur_path ? cur_path : ".");
 -		cur_word = concat_dir_and_file (expanded, text);
 +		cur_word = mhl_str_dir_plus_file (expanded, text);
- 		g_free (expanded);
+ 		mhl_mem_free (expanded);
  		canonicalize_pathname (cur_word);
  		cur_path = strchr (cur_path, 0) + 1;
  		init_state = state;
  	    }
  	    found =
  		filename_completion_function (cur_word,
 -					      state - init_state);
 +					      state - init_state, flags);
  	    if (!found) {
- 		g_free (cur_word);
+ 		mhl_mem_free (cur_word);
  		cur_word = NULL;
  	    }
  	}
      }
  
      if (!found) {
- 	g_free (path);
 -	look_for_executables = 0;
+ 	mhl_mem_free (path);
  	path = NULL;
  	return NULL;
      }
      if ((p = strrchr (found, PATH_SEP)) != NULL) {
  	p++;
- 
 -	p = g_strdup (p);
 -	mhl_mem_free (found);
 -	return p;
 +	SHELL_ESCAPED_STR e_p = mhl_shell_escape_dup(p);
 +	mhl_mem_free(found);
 +	return e_p.s;
      }
      return found;
  
@@@ -566,7 -521,7 +565,7 @@@ match_compare (const void *a, const voi
     as the second. 
     In case no matches were found we return NULL. */
  static char **
 -completion_matches (char *text, CompletionFunction entry_function)
 +completion_matches (char *text, CompletionFunction entry_function, INPUT_COMPLETE_FLAGS flags)
  {
      /* Number of slots in match_list. */
      int match_list_size;
@@@ -582,7 -537,7 +581,7 @@@
  
      match_list[1] = NULL;
  
 -    while ((string = (*entry_function) (text, matches)) != NULL){
 +    while ((string = (*entry_function) (text, matches, flags)) != NULL){
          if (matches + 1 == match_list_size)
  	    match_list = (char **) g_realloc (match_list, ((match_list_size += 30) + 1) * sizeof (char *));
          match_list[++matches] = string;
@@@ -618,7 -573,7 +617,7 @@@
  		    if (c1 != c2) break;
  		
  		if (!c1 && !match_list [j][si]){ /* Two equal strings */
- 		    g_free (match_list [j]);
+ 		    mhl_mem_free (match_list [j]);
  		    j++;
  		    if (j > matches)
  		        break;
@@@ -634,7 -589,7 +633,7 @@@
  	    match_list[0] = g_strndup(match_list[1], low);
  	}
      } else {				/* There were no matches. */
-         g_free (match_list);
+         mhl_mem_free (match_list);
          match_list = NULL;
      }
      return match_list;
@@@ -642,12 -597,14 +641,12 @@@
  
  /* Check if directory completion is needed */
  static int
 -check_is_cd (const char *text, int start, int flags)
 +check_is_cd (const char *text, int start, INPUT_COMPLETE_FLAGS flags)
  {
      const char *p, *q;
  
 -    if (flags & INPUT_COMPLETE_CD)
 -	return 1;
 -
 -    if (!(flags & INPUT_COMPLETE_COMMANDS))
 +    SHOW_C_CTX("check_is_cd");
 +    if (!(flags & INPUT_COMPLETE_CD))
  	return 0;
  
      /* Skip initial spaces */
@@@ -666,20 -623,19 +665,20 @@@
  
  /* Returns an array of matches, or NULL if none. */
  static char **
 -try_complete (char *text, int *start, int *end, int flags)
 +try_complete (char *text, int *start, int *end, INPUT_COMPLETE_FLAGS flags)
  {
 -    int in_command_position = 0, i;
 +    int in_command_position = 0;
      char *word, c;
      char **matches = NULL;
      const char *command_separator_chars = ";|&{(`";
      char *p = NULL, *q = NULL, *r = NULL;
      int is_cd = check_is_cd (text, *start, flags);
  
 -    ignore_filenames = 0;
 +    SHOW_C_CTX("try_complete");
 +
      c = text [*end];
      text [*end] = 0;
 -    word = g_strdup (text + *start);
 +    word = mhl_str_dup (text + *start);
      text [*end] = c;
  
      /* Determine if this could be a command word. It is if it appears at
@@@ -687,16 -643,9 +686,16 @@@
         appears after a character that separates commands. And we have to
         be in a INPUT_COMPLETE_COMMANDS flagged Input line. */
      if (!is_cd && (flags & INPUT_COMPLETE_COMMANDS)){
 -        i = *start - 1;
 -        while (i > -1 && (text[i] == ' ' || text[i] == '\t'))
 -            i--;
 +        int i = *start - 1;
 +	for (i = *start - 1; i > -1; i--) {
 +	    if (text[i] == ' ' || text[i] == '\t'){
 +		if (i == 0 ) continue;
 +		if (text[i-1] != '\\') {
 +		    i--;
 +		    break;
 +		}
 +	    }
 +	}
          if (i < 0)
  	    in_command_position++;
          else if (strchr (command_separator_chars, text[i])){
@@@ -730,19 -679,17 +729,19 @@@
      	    p = q + 1;
      	q = NULL;
      }
 -    
 +
      /* Command substitution? */
      if (p > q && p > r){
 -        matches = completion_matches (p + 1, command_completion_function);
 +        SHOW_C_CTX("try_complete:cmd_backq_subst");
 +        matches = completion_matches (p + 1, command_completion_function, flags & (~INPUT_COMPLETE_FILENAMES));
          if (matches)
              *start += p + 1 - word;
      }
  
      /* Variable name? */
      else if  (q > p && q > r){
 -        matches = completion_matches (q, variable_completion_function);
 +        SHOW_C_CTX("try_complete:var_subst");
 +        matches = completion_matches (q, variable_completion_function, flags);
          if (matches)
              *start += q - word;
      }
@@@ -750,8 -697,7 +749,8 @@@
      /* Starts with '@', then look through the known hostnames for 
         completion first. */
      else if (r > p && r > q){
 -        matches = completion_matches (r, hostname_completion_function);
 +        SHOW_C_CTX("try_complete:host_subst");
 +        matches = completion_matches (r, hostname_completion_function, flags);
          if (matches)
              *start += r - word;
      }
@@@ -759,48 -705,28 +758,48 @@@
      /* Starts with `~' and there is no slash in the word, then
         try completing this word as a username. */
      if (!matches && *word == '~' && (flags & INPUT_COMPLETE_USERNAMES) && !strchr (word, PATH_SEP))
 -        matches = completion_matches (word, username_completion_function);
 +    {
 +        SHOW_C_CTX("try_complete:user_subst");
 +        matches = completion_matches (word, username_completion_function, flags);
 +    }
  
  
      /* And finally if this word is in a command position, then
         complete over possible command names, including aliases, functions,
         and command names. */
      if (!matches && in_command_position)
 -        matches = completion_matches (word, command_completion_function);
 +    {
 +        SHOW_C_CTX("try_complete:cmd_subst");
 +        matches = completion_matches (word, command_completion_function, flags & (~INPUT_COMPLETE_FILENAMES));
 +    }
          
      else if (!matches && (flags & INPUT_COMPLETE_FILENAMES)){
 -    	if (is_cd)
 -    	    ignore_filenames = 1;
 -    	matches = completion_matches (word, filename_completion_function);
 -    	ignore_filenames = 0;
 +	if (is_cd)
 +	    flags &= ~(INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_COMMANDS);
 +	SHOW_C_CTX("try_complete:filename_subst_1");
 +	matches = completion_matches (word, filename_completion_function, flags);
      	if (!matches && is_cd && *word != PATH_SEP && *word != '~'){
      	    char *p, *q = text + *start;
 -    	    
 -    	    for (p = text; *p && p < q && (*p == ' ' || *p == '\t'); p++);
 +
 +	    for (p = text; *p && p < q; p++){
 +		if (*p == ' ' || *p == '\t') {
 +		    if (p == text) continue;
 +		    if (*(p-1) == '\\') {
 +			p--;
 +			break;
 +		    }
 +		}
 +	    }
      	    if (!strncmp (p, "cd", 2))
 -    	        for (p += 2; *p && p < q && (*p == ' ' || *p == '\t'); p++);
 +		for (p += 2; *p && p < q && (*p == ' ' || *p == '\t'); p++){
 +		    if (p == text) continue;
 +		    if (*(p-1) == '\\') {
 +			p--;
 +			break;
 +		    }
 +		}
      	    if (p == q){
 -		char * const cdpath_ref = g_strdup (getenv ("CDPATH"));
 +		char * const cdpath_ref = mhl_str_dup (getenv ("CDPATH"));
  		char *cdpath = cdpath_ref;
  		char c, *s, *r;
  
@@@ -815,20 -741,21 +814,20 @@@
  		    c = *s; 
  		    *s = 0;
  		    if (*cdpath){
 -			r = concat_dir_and_file (cdpath, word);
 -		        ignore_filenames = 1;
 -    	    		matches = completion_matches (r, filename_completion_function);
 -    	    		ignore_filenames = 0;
 -    	    		mhl_mem_free (r);
 +			r = mhl_str_dir_plus_file (cdpath, word);
 +			SHOW_C_CTX("try_complete:filename_subst_2");
 +			matches = completion_matches (r, filename_completion_function, flags);
- 			g_free (r);
++			mhl_mem_free (r);
  		    }
  		    *s = c;
  		    cdpath = s + 1;
  		}
- 		g_free (cdpath_ref);
+ 		mhl_mem_free (cdpath_ref);
      	    }
      	}
      }
  
-     g_free (word);
+     mhl_mem_free (word);
  
      return matches;
  }
@@@ -840,8 -767,8 +839,8 @@@ void free_completions (WInput *in
      if (!in->completions)
      	return;
      for (p=in->completions; *p; p++)
-     	g_free (*p);
-     g_free (in->completions);
+     	mhl_mem_free (*p);
+     mhl_mem_free (in->completions);
      in->completions = NULL;
  }
  
@@@ -990,21 -917,15 +989,21 @@@ complete_engine (WInput *in, int what_t
      if (!in->completions){
      	end = in->point;
          for (start = end ? end - 1 : 0; start > -1; start--)
 -    	    if (strchr (" \t;|<>", in->buffer [start]))
 -    	        break;
 +    	    if (strchr (" \t;|<>", in->buffer [start])){
 +    		if (start > 0 && in->buffer [start-1] == '\\')
 +    		    continue;
 +    		else
 +    		    break;
 +    	    }
      	if (start < end)
      	    start++;
      	in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
      }
 +    
      if (in->completions){
      	if (what_to_do & DO_INSERTION || ((what_to_do & DO_QUERY) && !in->completions[1])) {
 -    	    if (insert_text (in, in->completions [0], strlen (in->completions [0]))){
 +	        char * complete = in->completions [0];
 +	    if (insert_text (in, complete, strlen (complete))){
      	        if (in->completions [1])
      	    	    beep ();
  		else
@@@ -1019,11 -940,10 +1018,11 @@@
      	    char **p, *q;
      	    Dlg_head *query_dlg;
      	    WListbox *query_list;
 -    	    
 -    	    for (p=in->completions + 1; *p; count++, p++)
 -    	    	if ((i = strlen (*p)) > maxlen)
 -    	    	    maxlen = i;
 +
 +    	    for (p=in->completions + 1; *p; count++, p++) {
 +		if ((i = strlen (*p)) > maxlen)
 +		    maxlen = i;
 +	    }
      	    start_x = in->widget.x;
      	    start_y = in->widget.y;
      	    if (start_y - 2 >= count) {
diff --combined src/cons.handler.c
index 1fe35b0,83678cf..21a11fe
--- a/src/cons.handler.c
+++ b/src/cons.handler.c
@@@ -28,8 -28,6 +28,8 @@@
  #endif
  #include <unistd.h>
  
 +#include <mhl/string.h>
 +
  #include "global.h"
  #include "tty.h"
  #include "cons.saver.h"
@@@ -145,7 -143,7 +145,7 @@@ handle_console_linux (unsigned char act
  	    open ("/dev/null", O_WRONLY);
  	    if (tty_name) {
  		/* Exec the console save/restore handler */
 -		mc_conssaver = concat_dir_and_file (SAVERDIR, "cons.saver");
 +		mc_conssaver = mhl_str_dir_plus_file (SAVERDIR, "cons.saver");
  		execl (mc_conssaver, "cons.saver", tty_name, (char *) NULL);
  	    }
  	    /* Console is not a tty or execl() failed */
@@@ -267,7 -265,7 +267,7 @@@ console_shutdown (void
      if (!console_flag)
  	return;
  
-     g_free (screen_shot.buf);
+     mhl_mem_free (screen_shot.buf);
  
      console_flag = 0;
  }
diff --combined src/dialog.c
index a076288,1f9e37c..043f7de
--- a/src/dialog.c
+++ b/src/dialog.c
@@@ -24,7 -24,7 +24,8 @@@
  #include <stdio.h>
  #include <string.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -218,9 -218,9 +219,9 @@@ create_dlg (int y1, int x1, int lines, 
      /* Strip existing spaces, add one space before and after the title */
      if (title) {
  	char *t;
 -	t = g_strstrip (g_strdup (title));
 +	t = g_strstrip (mhl_str_dup (title));
  	new_d->title = g_strconcat (" ", t, " ", (char *) NULL);
- 	g_free (t);
+ 	mhl_mem_free (t);
      }
  
      return (new_d);
@@@ -815,11 -815,11 +816,11 @@@ destroy_dlg (Dlg_head *h
      c = h->current;
      for (i = 0; i < h->count; i++) {
  	c = c->next;
- 	g_free (h->current);
+ 	mhl_mem_free (h->current);
  	h->current = c;
      }
-     g_free (h->title);
-     g_free (h);
+     mhl_mem_free (h->title);
+     mhl_mem_free (h);
  
      do_refresh ();
  }
diff --combined src/dir.c
index c98271a,2839ce2..597d0c1
--- a/src/dir.c
+++ b/src/dir.c
@@@ -24,7 -24,7 +24,8 @@@
  #include <string.h>
  #include <sys/stat.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -255,7 -255,7 +256,7 @@@ clean_dir (dir_list *list, int count
      int i;
  
      for (i = 0; i < count; i++){
- 	g_free (list->list [i].fname);
+ 	mhl_mem_free (list->list [i].fname);
  	list->list [i].fname = 0;
      }
  }
@@@ -274,7 -274,7 +275,7 @@@ add_dotdot_to_list (dir_list *list, in
  
      memset (&(list->list) [index], 0, sizeof(file_entry));
      (list->list) [index].fnamelen = 2;
 -    (list->list) [index].fname = g_strdup ("..");
 +    (list->list) [index].fname = mhl_str_dup ("..");
      (list->list) [index].f.link_to_dir = 0;
      (list->list) [index].f.stale_link = 0;
      (list->list) [index].f.dir_size_computed = 0;
@@@ -421,7 -421,7 +422,7 @@@ do_load_dir (const char *path, dir_lis
  	    return next_free;
  	}
  	list->list[next_free].fnamelen = NLENGTH (dp);
 -	list->list[next_free].fname = g_strdup (dp->d_name);
 +	list->list[next_free].fname = mhl_str_dup (dp->d_name);
  	list->list[next_free].f.marked = 0;
  	list->list[next_free].f.link_to_dir = link_to_dir;
  	list->list[next_free].f.stale_link = stale_link;
@@@ -472,9 -472,9 +473,9 @@@ alloc_dir_copy (int size
  	if (dir_copy.list){
  
  	    for (i = 0; i < dir_copy.size; i++) {
- 		g_free (dir_copy.list [i].fname);
+ 		mhl_mem_free (dir_copy.list [i].fname);
  	    }
- 	    g_free (dir_copy.list);
+ 	    mhl_mem_free (dir_copy.list);
  	    dir_copy.list = 0;
  	}
  
@@@ -573,7 -573,7 +574,7 @@@ do_reload_dir (const char *path, dir_li
  	}
  
  	list->list[next_free].fnamelen = NLENGTH (dp);
 -	list->list[next_free].fname = g_strdup (dp->d_name);
 +	list->list[next_free].fname = mhl_str_dup (dp->d_name);
  	list->list[next_free].f.link_to_dir = link_to_dir;
  	list->list[next_free].f.stale_link = stale_link;
  	list->list[next_free].f.dir_size_computed = 0;
diff --combined src/ecs-test.c
index e7f64e5,a33468a..963a63b
--- a/src/ecs-test.c
+++ b/src/ecs-test.c
@@@ -29,13 -29,11 +29,13 @@@
  #include <locale.h>
  #include <stdio.h>
  
 +#include <mhl/types.h>
 +
  #include "global.h"
  #include "ecs.h"
  
  #ifdef EXTCHARSET_ENABLED
 -static gboolean
 +static bool
  change_locale(const char *loc)
  {
  	const char *ident;
@@@ -67,7 -65,7 +67,7 @@@ test_locale_en_US_UTF_8(void
  	const char     *teststr_c   = "Zuckert\374te";
  	ecs_char       *ecs;
  	char           *mbs;
 -	gboolean        valid;
 +	bool        valid;
  
  	if (!change_locale("en_US.UTF-8")) return;
  
@@@ -77,12 -75,12 +77,12 @@@
  	valid = ecs_mbstr_to_str(&ecs, teststr_mb);
  	assert(valid);
  	assert(ecs_strlen(ecs) == 10);
- 	g_free(ecs);
+ 	mhl_mem_free(ecs);
  
  	valid = ecs_str_to_mbstr(&mbs, teststr_ecs);
  	assert(valid);
  	assert(strlen(mbs) == 11);
- 	g_free(mbs);
+ 	mhl_mem_free(mbs);
  }
  #endif
  
diff --combined src/ecs.c
index 3fa3da6,4e701bb..a38c54e
--- a/src/ecs.c
+++ b/src/ecs.c
@@@ -27,9 -27,6 +27,9 @@@
  #include <assert.h>
  #include <ctype.h>
  
 +#include <mhl/types.h>
 +#include <mhl/string.h>
 +
  #include "global.h"
  #include "ecs.h"
  
@@@ -37,7 -34,7 +37,7 @@@
   * String type conversion
   */
  
 -extern gboolean ecs_mbstr_to_str(ecs_char **ret_str, const char *s)
 +extern bool ecs_mbstr_to_str(ecs_char **ret_str, const char *s)
  {
  #ifdef EXTCHARSET_ENABLED
  	size_t maxlen, len;
@@@ -48,7 -45,7 +48,7 @@@
  	str = g_new(ecs_char, maxlen + 1);
  	len = mbstowcs(str, s, maxlen + 1);
  	if (len == (size_t) -1) {
- 		g_free(str);
+ 		mhl_mem_free(str);
  		return FALSE;
  	}
  
@@@ -56,12 -53,12 +56,12 @@@
  	*ret_str = g_renew(ecs_char, str, len + 1);
  	return TRUE;
  #else
 -	*ret_str = g_strdup(s);
 +	*ret_str = mhl_str_dup(s);
  	return TRUE;
  #endif
  }
  
 -extern gboolean ecs_str_to_mbstr(char **ret_str, const ecs_char *s)
 +extern bool ecs_str_to_mbstr(char **ret_str, const ecs_char *s)
  {
  #ifdef EXTCHARSET_ENABLED
  	size_t maxlen, len;
@@@ -72,7 -69,7 +72,7 @@@
  	str = g_new(char, maxlen + 1);
  	len = wcstombs(str, s, maxlen + 1);
  	if (len == (size_t) -1) {
- 		g_free(str);
+ 		mhl_mem_free(str);
  		return FALSE;
  	}
  
@@@ -80,7 -77,7 +80,7 @@@
  	*ret_str = g_renew(char, str, len + 1);
  	return TRUE;
  #else
 -	*ret_str = g_strdup(s);
 +	*ret_str = mhl_str_dup(s);
  	return TRUE;
  #endif
  }
@@@ -103,57 -100,57 +103,57 @@@
  	(cf(c))
  #endif
  
 -extern gboolean ecs_isalnum(ecs_char c)
 +extern bool ecs_isalnum(ecs_char c)
  {
  	return ECS_CTYPE(iswalnum, isalnum, c);
  }
  
 -extern gboolean ecs_isalpha(ecs_char c)
 +extern bool ecs_isalpha(ecs_char c)
  {
  	return ECS_CTYPE(iswalpha, isalpha, c);
  }
  
 -extern gboolean ecs_iscntrl(ecs_char c)
 +extern bool ecs_iscntrl(ecs_char c)
  {
  	return ECS_CTYPE(iswcntrl, iscntrl, c);
  }
  
 -extern gboolean ecs_isdigit(ecs_char c)
 +extern bool ecs_isdigit(ecs_char c)
  {
  	return ECS_CTYPE(iswdigit, isdigit, c);
  }
  
 -extern gboolean ecs_isgraph(ecs_char c)
 +extern bool ecs_isgraph(ecs_char c)
  {
  	return ECS_CTYPE(iswgraph, isgraph, c);
  }
  
 -extern gboolean ecs_islower(ecs_char c)
 +extern bool ecs_islower(ecs_char c)
  {
  	return ECS_CTYPE(iswlower, islower, c);
  }
  
 -extern gboolean ecs_isprint(ecs_char c)
 +extern bool ecs_isprint(ecs_char c)
  {
  	return ECS_CTYPE(iswprint, isprint, c);
  }
  
 -extern gboolean ecs_ispunct(ecs_char c)
 +extern bool ecs_ispunct(ecs_char c)
  {
  	return ECS_CTYPE(iswpunct, ispunct, c);
  }
  
 -extern gboolean ecs_isspace(ecs_char c)
 +extern bool ecs_isspace(ecs_char c)
  {
  	return ECS_CTYPE(iswspace, isspace, c);
  }
  
 -extern gboolean ecs_isupper(ecs_char c)
 +extern bool ecs_isupper(ecs_char c)
  {
  	return ECS_CTYPE(iswupper, isupper, c);
  }
  
 -extern gboolean ecs_isxdigit(ecs_char c)
 +extern bool ecs_isxdigit(ecs_char c)
  {
  	return ECS_CTYPE(iswxdigit, isxdigit, c);
  }
@@@ -317,7 -314,7 +317,7 @@@ ecs_strlcat(ecs_char *dst, const ecs_ch
  	return di + ecs_strlcpy(dst + di, src, dstsize - di);
  }
  
 -gboolean
 +bool
  ecs_strbox(const ecs_char *s, size_t *ret_width, size_t *ret_height)
  {
  	size_t nlines = 0, ncolumns = 0, colindex = 0, i;
diff --combined src/ecs.h
index 9ba672c,193494f..98e9a9a
--- a/src/ecs.h
+++ b/src/ecs.h
@@@ -44,33 -44,31 +44,33 @@@ typedef char ecs_char
  #  define ECS_STR(s)		(s)
  #endif
  
 +#include <mhl/types.h>
 +
  /*
   * String conversion functions between the wide character encoding and
   * the multibyte encoding. The returned strings should be freed using
-  * g_free after use. The return value is TRUE if the string is valid
+  * mhl_mem_free after use. The return value is TRUE if the string is valid
   * and has been converted, FALSE otherwise.
   */
  
 -extern gboolean ecs_mbstr_to_str(ecs_char **ret_str, const char *);
 -extern gboolean ecs_str_to_mbstr(char **ret_str, const ecs_char *);
 +extern bool ecs_mbstr_to_str(ecs_char **ret_str, const char *);
 +extern bool ecs_str_to_mbstr(char **ret_str, const ecs_char *);
  
  /*
   * Replacements for the ISO C90 <ctype.h> functions.
   */
  
 -extern gboolean ecs_isalnum(ecs_char);
 -extern gboolean ecs_isalpha(ecs_char);
 -extern gboolean ecs_iscntrl(ecs_char);
 -extern gboolean ecs_isdigit(ecs_char);
 -extern gboolean ecs_isgraph(ecs_char);
 -extern gboolean ecs_islower(ecs_char);
 -extern gboolean ecs_isprint(ecs_char);
 -extern gboolean ecs_ispunct(ecs_char);
 -extern gboolean ecs_isspace(ecs_char);
 -extern gboolean ecs_isupper(ecs_char);
 -extern gboolean ecs_isxdigit(ecs_char);
 +extern bool ecs_isalnum(ecs_char);
 +extern bool ecs_isalpha(ecs_char);
 +extern bool ecs_iscntrl(ecs_char);
 +extern bool ecs_isdigit(ecs_char);
 +extern bool ecs_isgraph(ecs_char);
 +extern bool ecs_islower(ecs_char);
 +extern bool ecs_isprint(ecs_char);
 +extern bool ecs_ispunct(ecs_char);
 +extern bool ecs_isspace(ecs_char);
 +extern bool ecs_isupper(ecs_char);
 +extern bool ecs_isxdigit(ecs_char);
  
  /*
   * Replacements for the ISO C90 <string.h> functions.
@@@ -107,7 -105,7 +107,7 @@@ extern size_t ecs_strlcat(ecs_char *, c
   * displayed on screen. Returns TRUE if all characters in the string are
   * either '\n' or printable, according to the current locale. If the
   * return value is FALSE, ''width'' and ''height'' are not modified. */
 -extern gboolean ecs_strbox(const ecs_char *, size_t *ret_width,
 +extern bool ecs_strbox(const ecs_char *, size_t *ret_width,
  	size_t *ret_height);
  
  #endif
diff --combined src/execute.c
index 913a486,aa4f3db..ee56d81
--- a/src/execute.c
+++ b/src/execute.c
@@@ -19,7 -19,7 +19,8 @@@
  
  #include <signal.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -101,7 -101,7 +102,7 @@@ do_execute (const char *shell, const ch
      char *old_vfs_dir = 0;
  
      if (!vfs_current_is_local ())
 -	old_vfs_dir = g_strdup (vfs_get_current_dir ());
 +	old_vfs_dir = mhl_str_dup (vfs_get_current_dir ());
  #endif				/* USE_VFS */
  
      save_cwds_stat ();
@@@ -163,7 -163,7 +164,7 @@@
  #ifdef USE_VFS
      if (old_vfs_dir) {
  	mc_chdir (old_vfs_dir);
- 	g_free (old_vfs_dir);
+ 	mhl_mem_free (old_vfs_dir);
      }
  #endif				/* USE_VFS */
  
@@@ -197,7 -197,7 +198,7 @@@ shell_execute (const char *command, in
  #endif				/* HAVE_SUBSHELL_SUPPORT */
  	do_execute (shell, cmd ? cmd : command, flags | EXECUTE_AS_SHELL);
  
-     g_free (cmd);
+     mhl_mem_free (cmd);
  }
  
  
@@@ -364,12 -364,12 +365,12 @@@ execute_with_vfs_arg (const char *comma
       * the command, so make a copy.  Smarter VFS code would make the code
       * below unnecessary.
       */
 -    fn = g_strdup (filename);
 +    fn = mhl_str_dup (filename);
      mc_stat (localcopy, &st);
      mtime = st.st_mtime;
      do_execute (command, localcopy, EXECUTE_INTERNAL);
      mc_stat (localcopy, &st);
      mc_ungetlocalcopy (fn, localcopy, mtime != st.st_mtime);
-     g_free (localcopy);
-     g_free (fn);
+     mhl_mem_free (localcopy);
+     mhl_mem_free (fn);
  }
diff --combined src/ext.c
index 329928b,bfd76ee..134411a
--- a/src/ext.c
+++ b/src/ext.c
@@@ -27,7 -27,7 +27,8 @@@
  #include <string.h>
  #include <unistd.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -53,7 -53,7 +54,7 @@@ static char *data = NULL
  void
  flush_extension_file (void)
  {
-     g_free (data);
+     mhl_mem_free (data);
      data = NULL;
  }
  
@@@ -122,14 -122,14 +123,14 @@@ exec_extension (const char *filename, c
  		    unlink (file_name);
  		    if (localcopy) {
  			mc_ungetlocalcopy (filename, localcopy, 0);
- 			g_free (localcopy);
+ 			mhl_mem_free (localcopy);
  		    }
- 		    g_free (file_name);
+ 		    mhl_mem_free (file_name);
  		    return;
  		}
  		fputs (parameter, cmd_file);
  		written_nonspace = 1;
- 		g_free (parameter);
+ 		mhl_mem_free (parameter);
  	    } else {
  		size_t len = strlen (prompt);
  
@@@ -157,7 -157,7 +158,7 @@@
  		    data += i - 1;
  		} else if ((i = check_format_var (data, &v)) > 0 && v) {
  		    fputs (v, cmd_file);
- 		    g_free (v);
+ 		    mhl_mem_free (v);
  		    data += i;
  		} else {
  		    char *text;
@@@ -168,7 -168,7 +169,7 @@@
  			    if (localcopy == NULL) {
  				fclose (cmd_file);
  				unlink (file_name);
- 				g_free (file_name);
+ 				mhl_mem_free (file_name);
  				return;
  			    }
  			    mc_stat (localcopy, &mystat);
@@@ -185,7 -185,7 +186,7 @@@
  			strcpy (p, text);
  			p = strchr (p, 0);
  		    }
- 		    g_free (text);
+ 		    mhl_mem_free (text);
  		    written_nonspace = 1;
  		}
  	    }
@@@ -216,7 -216,7 +217,7 @@@
  
      if ((run_view && !written_nonspace) || is_cd) {
  	unlink (file_name);
- 	g_free (file_name);
+ 	mhl_mem_free (file_name);
  	file_name = NULL;
      } else {
  	/* Set executable flag on the command file ... */
@@@ -275,14 -275,14 +276,14 @@@
  	}
      }
  
-     g_free (file_name);
-     g_free (cmd);
+     mhl_mem_free (file_name);
+     mhl_mem_free (cmd);
  
      if (localcopy) {
  	mc_stat (localcopy, &mystat);
  	mc_ungetlocalcopy (filename, localcopy,
  			   localmtime != mystat.st_mtime);
- 	g_free (localcopy);
+ 	mhl_mem_free (localcopy);
      }
  }
  
@@@ -305,8 -305,8 +306,8 @@@ get_file_type_local (const char *filena
      char *command = g_strconcat (FILE_CMD, tmp, " 2>/dev/null", (char *) 0);
      FILE *f = popen (command, "r");
  
-     g_free (tmp);
-     g_free (command);
+     mhl_mem_free (tmp);
+     mhl_mem_free (command);
      if (f != NULL) {
  #ifdef __QNXNTO__
  	if (setvbuf (f, NULL, _IOFBF, 0) != 0) {
@@@ -387,7 -387,7 +388,7 @@@ regex_check_type (const char *filename
  	    /* No data */
  	    content_string[0] = 0;
  	}
- 	g_free (realname);
+ 	mhl_mem_free (realname);
      }
  
      if (got_data == -1) {
@@@ -441,22 -441,22 +442,22 @@@ regex_command (const char *filename, co
  	int mc_user_ext = 1;
  	int home_error = 0;
  
 -	extension_file = concat_dir_and_file (home_dir, MC_USER_EXT);
 +	extension_file = mhl_str_dir_plus_file (home_dir, MC_USER_EXT);
  	if (!exist_file (extension_file)) {
- 	    g_free (extension_file);
+ 	    mhl_mem_free (extension_file);
  	  check_stock_mc_ext:
 -	    extension_file = concat_dir_and_file (mc_home, MC_LIB_EXT);
 +	    extension_file = mhl_str_dir_plus_file (mc_home, MC_LIB_EXT);
  	    mc_user_ext = 0;
  	}
  	data = load_file (extension_file);
- 	g_free (extension_file);
+ 	mhl_mem_free (extension_file);
  	if (data == NULL)
  	    return 0;
  
  	if (!strstr (data, "default/")) {
  	    if (!strstr (data, "regex/") && !strstr (data, "shell/")
  		&& !strstr (data, "type/")) {
- 		g_free (data);
+ 		mhl_mem_free (data);
  		data = NULL;
  		if (mc_user_ext) {
  		    home_error = 1;
@@@ -470,7 -470,7 +471,7 @@@
  			"the installation failed.  Please fetch a fresh "
  			"copy from the Midnight Commander package."),
  			mc_home);
- 		    g_free (title);
+ 		    mhl_mem_free (title);
  		    return 0;
  		}
  	    }
@@@ -482,7 -482,7 +483,7 @@@
  		"changed with version 3.0.  You may either want to copy "
  		"it from %smc.ext or use that file as an example of how "
  		"to write it."), MC_USER_EXT, mc_home);
- 	    g_free (title);
+ 	    mhl_mem_free (title);
  	}
      }
      mc_stat (filename, &mystat);
@@@ -591,11 -591,11 +592,11 @@@
  			 * we get filename as a pointer from current_panel->dir).
  			 */
  			if (p < q) {
 -			    char *filename_copy = g_strdup (filename);
 +			    char *filename_copy = mhl_str_dup (filename);
  
  			    exec_extension (filename_copy, r + 1, move_dir,
  					    view_at_line_number);
- 			    g_free (filename_copy);
+ 			    mhl_mem_free (filename_copy);
  
  			    ret = 1;
  			}
diff --combined src/file.c
index c5dac13,97e7160..1a367ea
--- a/src/file.c
+++ b/src/file.c
@@@ -45,13 -45,11 +45,13 @@@
  #include <errno.h>
  #include <stdio.h>
  #include <string.h>
 -
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <unistd.h>
  
 +#include <mhl/types.h>
 +#include <mhl/memory.h>
 +#include <mhl/escape.h>
  #include <mhl/string.h>
  
  #include "global.h"
@@@ -67,7 -65,6 +67,7 @@@
  #include "widget.h"
  #include "wtools.h"
  #include "background.h"		/* we_are_background */
 +#include "util.h"
  
  /* Needed for current_panel, other_panel and WTree */
  #include "dir.h"
@@@ -181,43 -178,37 +181,43 @@@ do_transform_source (FileOpContext *ctx
      for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) {
  	switch (ctx->dest_mask[j]) {
  	case '\\':
 -	    j++;
 -	    if (!isdigit ((unsigned char) ctx->dest_mask[j])) {
 -		/* Backslash followed by non-digit */
 -		switch (ctx->dest_mask[j]) {
 -		case 'U':
 -		    case_conv |= UP_SECT;
 -		    case_conv &= ~LOW_SECT;
 -		    break;
 -		case 'u':
 -		    case_conv |= UP_CHAR;
 -		    break;
 -		case 'L':
 -		    case_conv |= LOW_SECT;
 -		    case_conv &= ~UP_SECT;
 -		    break;
 -		case 'l':
 -		    case_conv |= LOW_CHAR;
 -		    break;
 -		case 'E':
 -		    case_conv = NO_CONV;
 -		    break;
 -		default:
 -		    /* Backslash as quote mark */
 -		    fntarget[k++] =
 -			convert_case (ctx->dest_mask[j], &case_conv);
 -		}
 +	    if (mhl_shell_is_char_escaped (&ctx->dest_mask[j])){
 +		fntarget[k++] = ctx->dest_mask[j++];
 +		fntarget[k++] = ctx->dest_mask[j];
  		break;
  	    } else {
 -		/* Backslash followed by digit */
 -		next_reg = ctx->dest_mask[j] - '0';
 -		/* Fall through */
 +		j++;
 +		if (!isdigit ((unsigned char) ctx->dest_mask[j])) {
 +		    /* Backslash followed by non-digit */
 +		    switch (ctx->dest_mask[j]) {
 +		    case 'U':
 +			case_conv |= UP_SECT;
 +			case_conv &= ~LOW_SECT;
 +			break;
 +		    case 'u':
 +			case_conv |= UP_CHAR;
 +			break;
 +		    case 'L':
 +			case_conv |= LOW_SECT;
 +			case_conv &= ~UP_SECT;
 +			break;
 +		    case 'l':
 +			case_conv |= LOW_CHAR;
 +			break;
 +		    case 'E':
 +			case_conv = NO_CONV;
 +			break;
 +		    default:
 +			/* Backslash as quote mark */
 +			fntarget[k++] =
 +			    convert_case (ctx->dest_mask[j], &case_conv);
 +		    }
 +		    break;
 +		} else {
 +		    /* Backslash followed by digit */
 +		    next_reg = ctx->dest_mask[j] - '0';
 +		    /* Fall through */
 +		}
  	    }
  
  	case '*':
@@@ -245,7 -236,7 +245,7 @@@
  static const char *
  transform_source (FileOpContext *ctx, const char *source)
  {
 -    char *s = g_strdup (source);
 +    char *s = mhl_str_dup (source);
      char *q;
      const char *p;
  
@@@ -256,7 -247,7 +256,7 @@@
  	    *q = ' ';
      }
      p = do_transform_source (ctx, s);
-     g_free (s);
+     mhl_mem_free (s);
      return p;
  }
  
@@@ -267,7 -258,7 +267,7 @@@ free_linklist (struct link **linklist
  
      for (lp = *linklist; lp != NULL; lp = lp2) {
  	lp2 = lp->next;
- 	g_free (lp);
+ 	mhl_mem_free (lp);
      }
      *linklist = NULL;
  }
@@@ -392,24 -383,24 +392,24 @@@ make_symlink (FileOpContext *ctx, cons
  	if (r) {
  	    p = g_strndup (src_path, r - src_path + 1);
  	    if (*dst_path == PATH_SEP)
 -		q = g_strdup (dst_path);
 +		q = mhl_str_dup (dst_path);
  	    else
  		q = g_strconcat (p, dst_path, (char *) NULL);
  	    s = strrchr (q, PATH_SEP);
  	    if (s) {
  		s[1] = 0;
  		s = g_strconcat (p, link_target, (char *) NULL);
- 		g_free (p);
+ 		mhl_mem_free (p);
  		g_strlcpy (link_target, s, sizeof (link_target));
- 		g_free (s);
+ 		mhl_mem_free (s);
  		s = diff_two_paths (q, link_target);
  		if (s) {
  		    g_strlcpy (link_target, s, sizeof (link_target));
- 		    g_free (s);
+ 		    mhl_mem_free (s);
  		}
  	    } else
- 		g_free (p);
- 	    g_free (q);
+ 		mhl_mem_free (p);
+ 	    mhl_mem_free (q);
  	}
      }
    retry_dst_symlink:
@@@ -760,7 -751,7 +760,7 @@@ copy_file_file (FileOpContext *ctx, con
      dst_status = DEST_FULL;	/* copy successful, don't remove target file */
  
    ret:
-     g_free (buf);
+     mhl_mem_free (buf);
  
      while (src_desc != -1 && mc_close (src_desc) < 0) {
  	temp_status = file_error (
@@@ -802,7 -793,7 +802,7 @@@
  	    }
  	}
  
 -	if (!appending) {
 +	if (!appending && ctx->preserve) {
  	    while (mc_chmod (dst_path, (src_mode & ctx->umask_kill))) {
  		temp_status = file_error (
  			_(" Cannot chmod target file \"%s\" \n %s "), dst_path);
@@@ -898,11 -889,11 +898,11 @@@ copy_dir_dir (FileOpContext *ctx, cons
  
  	if (move_over) {
  	    if (mc_rename (s, d) == 0) {
- 		g_free (parent_dirs);
+ 		mhl_mem_free (parent_dirs);
  		return FILE_CONT;
  	    }
  	}
 -	dest_dir = g_strdup (d);
 +	dest_dir = mhl_str_dup (d);
      } else {
  	/*
  	 * If the destination directory exists, we want to copy the whole
@@@ -917,14 -908,14 +917,14 @@@
  		_(" Destination \"%s\" must be a directory \n %s "), d);
  	    if (return_status == FILE_RETRY)
  		goto retry_dst_stat;
- 	    g_free (parent_dirs);
+ 	    mhl_mem_free (parent_dirs);
  	    return return_status;
  	}
  	/* Dive into subdir if exists */
  	if (toplevel && ctx->dive_into_subdirs) {
 -	    dest_dir = concat_dir_and_file (d, x_basename (s));
 +	    dest_dir = mhl_str_dir_plus_file (d, x_basename (s));
  	} else {
 -	    dest_dir = g_strdup (d);
 +	    dest_dir = mhl_str_dup (d);
  	    goto dont_mkdir;
  	}
      }
@@@ -968,11 -959,11 +968,11 @@@
  	    continue;
  
  	/* get the filename and add it to the src directory */
 -	path = concat_dir_and_file (s, next->d_name);
 +	path = mhl_str_dir_plus_file (s, next->d_name);
  
  	(*ctx->stat_func) (path, &buf);
  	if (S_ISDIR (buf.st_mode)) {
 -	    mdpath = concat_dir_and_file (dest_dir, next->d_name);
 +	    mdpath = mhl_str_dir_plus_file (dest_dir, next->d_name);
  	    /*
  	     * From here, we just intend to recursively copy subdirs, not
  	     * the double functionality of copying different when the target
@@@ -981,12 -972,12 +981,12 @@@
  	     */
  	    return_status = copy_dir_dir (ctx, path, mdpath, 0, 0, delete,
  				parent_dirs, progress_count, progress_bytes);
- 	    g_free (mdpath);
+ 	    mhl_mem_free (mdpath);
  	} else {
 -	    dest_file = concat_dir_and_file (dest_dir, x_basename (path));
 +	    dest_file = mhl_str_dir_plus_file (dest_dir, x_basename (path));
  	    return_status = copy_file_file (ctx, path, dest_file, 1,
  					    progress_count, progress_bytes, 0);
- 	    g_free (dest_file);
+ 	    mhl_mem_free (dest_file);
  	}
  	if (delete && return_status == FILE_CONT) {
  	    if (ctx->erase_at_end) {
@@@ -1007,7 -998,7 +1007,7 @@@
  		    return_status = erase_file (ctx, path, 0, 0, 0);
  	    }
  	}
- 	g_free (path);
+ 	mhl_mem_free (path);
      }
      mc_closedir (reading);
  
@@@ -1019,8 -1010,8 +1019,8 @@@
      }
  
    ret:
-     g_free (dest_dir);
-     g_free (parent_dirs);
+     mhl_mem_free (dest_dir);
+     mhl_mem_free (parent_dirs);
      return return_status;
  }
  
@@@ -1034,7 -1025,7 +1034,7 @@@ move_file_file (FileOpContext *ctx, con
  {
      struct stat src_stats, dst_stats;
      int return_status = FILE_CONT;
 -    gboolean copy_done = FALSE;
 +    bool copy_done = FALSE;
  
      if (file_progress_show_source (ctx, s) == FILE_ABORT
  	|| file_progress_show_target (ctx, d) == FILE_ABORT)
@@@ -1168,12 -1159,12 +1168,12 @@@ move_dir_dir (FileOpContext *ctx, cons
  
      mc_stat (s, &sbuf);
      if (mc_stat (d, &dbuf))
 -	destdir = g_strdup (d);	/* destination doesn't exist */
 +	destdir = mhl_str_dup (d);	/* destination doesn't exist */
      else if (!ctx->dive_into_subdirs) {
 -	destdir = g_strdup (d);
 +	destdir = mhl_str_dup (d);
  	move_over = 1;
      } else
 -	destdir = concat_dir_and_file (d, x_basename (s));
 +	destdir = mhl_str_dir_plus_file (d, x_basename (s));
  
      if (sbuf.st_dev == dbuf.st_dev && sbuf.st_ino == dbuf.st_ino) {
  	int msize = COLS - 36;
@@@ -1215,7 -1206,7 +1215,7 @@@
  	    if (return_status == FILE_RETRY)
  		goto retry_dst_stat;
  	}
- 	g_free (destdir);
+ 	mhl_mem_free (destdir);
  	return return_status;
      }
  
@@@ -1258,17 -1249,17 +1258,17 @@@
  		    erase_file (ctx, erase_list->name, 0, 0, 0);
  	    lp = erase_list;
  	    erase_list = erase_list->next;
- 	    g_free (lp);
+ 	    mhl_mem_free (lp);
  	}
      }
      erase_dir_iff_empty (ctx, s);
  
    ret:
-     g_free (destdir);
+     mhl_mem_free (destdir);
      while (erase_list) {
  	lp = erase_list;
  	erase_list = erase_list->next;
- 	g_free (lp);
+ 	mhl_mem_free (lp);
      }
      return return_status;
  }
@@@ -1330,9 -1321,9 +1330,9 @@@ recursive_erase (FileOpContext *ctx, co
  	    continue;
  	if (!strcmp (next->d_name, ".."))
  	    continue;
 -	path = concat_dir_and_file (s, next->d_name);
 +	path = mhl_str_dir_plus_file (s, next->d_name);
  	if (mc_lstat (path, &buf)) {
- 	    g_free (path);
+ 	    mhl_mem_free (path);
  	    mc_closedir (reading);
  	    return 1;
  	}
@@@ -1344,7 -1335,7 +1344,7 @@@
  	else
  	    return_status =
  		erase_file (ctx, path, progress_count, progress_bytes, 0);
- 	g_free (path);
+ 	mhl_mem_free (path);
      }
      mc_closedir (reading);
      if (return_status != FILE_CONT)
@@@ -1521,12 -1512,12 +1521,12 @@@ compute_dir_size (const char *dirname, 
  	if (strcmp (dirent->d_name, "..") == 0)
  	    continue;
  
 -	fullname = concat_dir_and_file (dirname, dirent->d_name);
 +	fullname = mhl_str_dir_plus_file (dirname, dirent->d_name);
  
  	res = mc_lstat (fullname, &s);
  
  	if (res != 0) {
- 	    g_free (fullname);
+ 	    mhl_mem_free (fullname);
  	    continue;
  	}
  
@@@ -1542,7 -1533,7 +1542,7 @@@
  	    (*ret_marked)++;
  	    *ret_total += s.st_size;
  	}
- 	g_free (fullname);
+ 	mhl_mem_free (fullname);
      }
  
      mc_closedir (dir);
@@@ -1578,12 -1569,12 +1578,12 @@@ panel_compute_totals (WPanel *panel, of
  	    double subdir_bytes = 0;
  
  	    dir_name =
 -		concat_dir_and_file (panel->cwd, panel->dir.list[i].fname);
 +		mhl_str_dir_plus_file (panel->cwd, panel->dir.list[i].fname);
  	    compute_dir_size (dir_name, &subdir_count, &subdir_bytes);
  
  	    *ret_marked += subdir_count;
  	    *ret_total += subdir_bytes;
- 	    g_free (dir_name);
+ 	    mhl_mem_free (dir_name);
  	} else {
  	    (*ret_marked)++;
  	    *ret_total += s->st_size;
@@@ -1701,10 -1692,10 +1701,10 @@@ panel_operate_generate_prompt (const WP
  
      if (single_source) {
  	i = fmd_xlen - strlen (format_string) - 4;
 -	g_snprintf (cmd_buf, sizeof (cmd_buf), format_string,
 +	snprintf (cmd_buf, sizeof (cmd_buf), format_string,
  		    name_trunc (single_source, i));
      } else {
 -	g_snprintf (cmd_buf, sizeof (cmd_buf), format_string,
 +	snprintf (cmd_buf, sizeof (cmd_buf), format_string,
  		    panel->marked);
  	i = strlen (cmd_buf) + 6 - fmd_xlen;
  	if (i > 0) {
@@@ -1829,7 -1820,7 +1829,7 @@@ panel_operate (void *source_panel, File
  	}
  	if (!*dest) {
  	    file_op_context_destroy (ctx);
- 	    g_free (dest);
+ 	    mhl_mem_free (dest);
  	    return 0;
  	}
      }
@@@ -1862,11 -1853,11 +1862,11 @@@
         invalid data. */
      if (dest) {
  	if (mc_setctl (dest, VFS_SETCTL_STALE_DATA, (void *) 1))
 -	    save_dest = g_strdup (dest);
 +	    save_dest = mhl_str_dup (dest);
      }
      if (panel->cwd) {
  	if (mc_setctl (panel->cwd, VFS_SETCTL_STALE_DATA, (void *) 1))
 -	    save_cwd = g_strdup (panel->cwd);
 +	    save_cwd = mhl_str_dup (panel->cwd);
      }
  
      /* Now, let's do the job */
@@@ -1886,7 -1877,7 +1886,7 @@@
  
  	/* The source and src_stat variables have been initialized before */
  #ifdef WITH_FULL_PATHS
 -	source_with_path = concat_dir_and_file (panel->cwd, source);
 +	source_with_path = mhl_str_dir_plus_file (panel->cwd, source);
  #endif				/* WITH_FULL_PATHS */
  
  	if (operation == OP_DELETE) {
@@@ -1901,11 -1892,11 +1901,11 @@@
  	    if (temp == NULL) {
  		value = transform_error;
  	    } else {
 -		char *temp2 = concat_dir_and_file (dest, temp);
 +		char *temp2 = mhl_str_dir_plus_file (dest, temp);
- 		g_free (dest);
+ 		mhl_mem_free (dest);
  		dest = temp2;
  		temp = NULL;
 -
 +		
  		switch (operation) {
  		case OP_COPY:
  		    /*
@@@ -1978,8 -1969,8 +1978,8 @@@
  	    src_stat = panel->dir.list[i].st;
  
  #ifdef WITH_FULL_PATHS
- 	    g_free (source_with_path);
+ 	    mhl_mem_free (source_with_path);
 -	    source_with_path = concat_dir_and_file (panel->cwd, source);
 +	    source_with_path = mhl_str_dir_plus_file (panel->cwd, source);
  #endif				/* WITH_FULL_PATHS */
  
  	    if (operation == OP_DELETE) {
@@@ -1995,10 -1986,7 +1995,10 @@@
  		if (temp == NULL)
  		    value = transform_error;
  		else {
 -		    char *temp2 = concat_dir_and_file (dest, temp);
 +		    char *temp2 = mhl_str_dir_plus_file (dest, temp);
 +
 +		    source_with_path = mhl_shell_unescape_buf(source_with_path);
 +		    temp2 = mhl_shell_unescape_buf(temp2);
  
  		    switch (operation) {
  		    case OP_COPY:
@@@ -2033,7 -2021,7 +2033,7 @@@
  			/* Unknown file operation */
  			abort ();
  		    }
- 		    g_free (temp2);
+ 		    mhl_mem_free (temp2);
  		}
  	    }			/* Copy or move operation */
  
@@@ -2065,20 -2053,20 +2065,20 @@@
  
      if (save_cwd) {
  	mc_setctl (save_cwd, VFS_SETCTL_STALE_DATA, NULL);
- 	g_free (save_cwd);
+ 	mhl_mem_free (save_cwd);
      }
      if (save_dest) {
  	mc_setctl (save_dest, VFS_SETCTL_STALE_DATA, NULL);
- 	g_free (save_dest);
+ 	mhl_mem_free (save_dest);
      }
  
      free_linklist (&linklist);
      free_linklist (&dest_dirs);
  #ifdef WITH_FULL_PATHS
-     g_free (source_with_path);
+     mhl_mem_free (source_with_path);
  #endif				/* WITH_FULL_PATHS */
-     g_free (dest);
-     g_free (ctx->dest_mask);
+     mhl_mem_free (dest);
+     mhl_mem_free (ctx->dest_mask);
      ctx->dest_mask = NULL;
  #ifdef WITH_BACKGROUND
      /* Let our parent know we are saying bye bye */
@@@ -2126,7 -2114,7 +2126,7 @@@ real_do_file_error (enum OperationMode 
  int
  file_error (const char *format, const char *file)
  {
 -    g_snprintf (cmd_buf, sizeof (cmd_buf), format,
 +    snprintf (cmd_buf, sizeof (cmd_buf), format,
  		path_trunc (file, 30), unix_error_string (errno));
  
      return do_file_error (cmd_buf);
@@@ -2142,7 -2130,7 +2142,7 @@@ files_error (const char *format, const 
      strcpy (nfile1, path_trunc (file1, 15));
      strcpy (nfile2, path_trunc (file2, 15));
  
 -    g_snprintf (cmd_buf, sizeof (cmd_buf), format, nfile1, nfile2,
 +    snprintf (cmd_buf, sizeof (cmd_buf), format, nfile1, nfile2,
  		unix_error_string (errno));
  
      return do_file_error (cmd_buf);
@@@ -2172,7 -2160,7 +2172,7 @@@ real_query_recursive (FileOpContext *ct
  
  	if (ctx->recursive_result != RECURSIVE_ABORT)
  	    do_refresh ();
- 	g_free (text);
+ 	mhl_mem_free (text);
      }
  
      switch (ctx->recursive_result) {
diff --combined src/filegui.c
index 9a4fc2f,1bbe527..e7814ac
--- a/src/filegui.c
+++ b/src/filegui.c
@@@ -52,7 -52,7 +52,8 @@@
  #include <sys/stat.h>
  #include <unistd.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "setup.h"		/* verbose */
@@@ -257,7 -257,7 +258,7 @@@ file_op_context_destroy_ui (FileOpConte
  
  	dlg_run_done (ui->op_dlg);
  	destroy_dlg (ui->op_dlg);
- 	g_free (ui);
+ 	mhl_mem_free (ui);
      }
  
      the_hint->widget.y = last_hint_line;
@@@ -321,7 -321,7 +322,7 @@@ file_eta_show (FileOpContext *ctx
  	eta_hours = ctx->eta_secs / (60 * 60);
  	eta_mins = (ctx->eta_secs - (eta_hours * 60 * 60)) / 60;
  	eta_s = ctx->eta_secs - (eta_hours * 60 * 60 + eta_mins * 60);
 -	g_snprintf (eta_buffer, sizeof (eta_buffer), _("ETA %d:%02d.%02d"),
 +	snprintf (eta_buffer, sizeof (eta_buffer), _("ETA %d:%02d.%02d"),
  		    eta_hours, eta_mins, eta_s);
      } else
  	*eta_buffer = 0;
@@@ -344,13 -344,13 +345,13 @@@ file_bps_show (FileOpContext *ctx
  	return;
  
      if (ctx->bps > 1024 * 1024) {
 -	g_snprintf (bps_buffer, sizeof (bps_buffer), _("%.2f MB/s"),
 +	snprintf (bps_buffer, sizeof (bps_buffer), _("%.2f MB/s"),
  		    ctx->bps / (1024 * 1024.0));
      } else if (ctx->bps > 1024) {
 -	g_snprintf (bps_buffer, sizeof (bps_buffer), _("%.2f KB/s"),
 +	snprintf (bps_buffer, sizeof (bps_buffer), _("%.2f KB/s"),
  		    ctx->bps / 1024.0);
      } else if (ctx->bps > 1) {
 -	g_snprintf (bps_buffer, sizeof (bps_buffer), _("%ld B/s"),
 +	snprintf (bps_buffer, sizeof (bps_buffer), _("%ld B/s"),
  		    ctx->bps);
      } else
  	*bps_buffer = 0;
@@@ -541,7 -541,7 +542,7 @@@ static struct 
  		NORMAL_BUTTON, rd_widgets [i].text, 0))
  
  #define ADD_RD_LABEL(ui,i,p1,p2)\
 -	g_snprintf (buffer, sizeof (buffer), rd_widgets [i].text, p1, p2);\
 +	snprintf (buffer, sizeof (buffer), rd_widgets [i].text, p1, p2);\
  	add_widget (ui->replace_dlg,\
  		label_new (rd_widgets [i].ypos, rd_widgets [i].xpos, buffer))
  
@@@ -882,7 -882,7 +883,7 @@@ file_mask_dialog (FileOpContext *ctx, F
      fmd_widgets[FMCB21].result = &ctx->dive_into_subdirs;
  
      /* filter out a possible password from def_text */
 -    def_text_secure = strip_password (g_strdup (def_text), 1);
 +    def_text_secure = strip_password (mhl_str_dup (def_text), 1);
  
      /* Create the dialog */
  
@@@ -905,10 -905,10 +906,10 @@@
    ask_file_mask:
  
      if ((val = quick_dialog_skip (&Quick_input, SKIP)) == B_CANCEL) {
- 	g_free (def_text_secure);
+ 	mhl_mem_free (def_text_secure);
  	return 0;
      }
-     g_free (def_text_secure);
+     mhl_mem_free (def_text_secure);
  
      if (ctx->follow_links)
  	ctx->stat_func = mc_stat;
@@@ -929,7 -929,7 +930,7 @@@
  
      orig_mask = source_mask;
      if (!dest_dir || !*dest_dir) {
- 	g_free (source_mask);
+ 	mhl_mem_free (source_mask);
  	return dest_dir;
      }
      if (source_easy_patterns) {
@@@ -940,7 -940,7 +941,7 @@@
  	error =
  	    re_compile_pattern (source_mask, strlen (source_mask),
  				&ctx->rx);
- 	g_free (source_mask);
+ 	mhl_mem_free (source_mask);
      } else
  	error =
  	    re_compile_pattern (source_mask, strlen (source_mask),
@@@ -949,14 -949,14 +950,14 @@@
      if (error) {
  	message (D_ERROR, MSG_ERROR, _("Invalid source pattern `%s' \n %s "),
  		    orig_mask, error);
- 	g_free (orig_mask);
+ 	mhl_mem_free (orig_mask);
  	goto ask_file_mask;
      }
-     g_free (orig_mask);
+     mhl_mem_free (orig_mask);
  
      tmpdest = dest_dir;
      dest_dir = tilde_expand(tmpdest);
-     g_free(tmpdest);
+     mhl_mem_free(tmpdest);
  
      ctx->dest_mask = strrchr (dest_dir, PATH_SEP);
      if (ctx->dest_mask == NULL)
@@@ -972,14 -972,14 +973,14 @@@
  	    && ((!only_one && !is_wildcarded (ctx->dest_mask))
  		|| (only_one && !mc_stat (dest_dir, &buf)
  		    && S_ISDIR (buf.st_mode)))))
 -	ctx->dest_mask = g_strdup ("*");
 +	ctx->dest_mask = mhl_str_dup ("*");
      else {
 -	ctx->dest_mask = g_strdup (ctx->dest_mask);
 +	ctx->dest_mask = mhl_str_dup (ctx->dest_mask);
  	*orig_mask = 0;
      }
      if (!*dest_dir) {
- 	g_free (dest_dir);
+ 	mhl_mem_free (dest_dir);
 -	dest_dir = g_strdup ("./");
 +	dest_dir = mhl_str_dup ("./");
      }
      if (val == B_USER)
  	*do_background = 1;
diff --combined src/filenot.c
index 7a67a0a,00b434a..c3c2e94
--- a/src/filenot.c
+++ b/src/filenot.c
@@@ -27,7 -27,7 +27,8 @@@
  #include <errno.h>
  #include <string.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  
@@@ -37,9 -37,9 +38,9 @@@ get_absolute_name (const char *file
      char dir[MC_MAXPATHLEN];
  
      if (file[0] == PATH_SEP)
 -	return g_strdup (file);
 +	return mhl_str_dup (file);
      mc_get_current_wd (dir, MC_MAXPATHLEN);
 -    return concat_dir_and_file (dir, file);
 +    return mhl_str_dir_plus_file (dir, file);
  }
  
  static int
@@@ -62,14 -62,14 +63,14 @@@ my_mkdir_rec (char *s, mode_t mode
  	return -1;
      }
  
 -    p = concat_dir_and_file (s, "..");
 +    p = mhl_str_dir_plus_file (s, "..");
      q = vfs_canon (p);
-     g_free (p);
+     mhl_mem_free (p);
  
      if (!(result = my_mkdir_rec (q, mode)))
  	result = mc_mkdir (s, mode);
  
-     g_free (q);
+     mhl_mem_free (q);
      return result;
  }
  
@@@ -84,7 -84,7 +85,7 @@@ my_mkdir (const char *s, mode_t mode
  	char *p = vfs_canon (s);
  
  	result = my_mkdir_rec (p, mode);
- 	g_free (p);
+ 	mhl_mem_free (p);
      }
      if (result == 0) {
  	my_s = get_absolute_name (s);
@@@ -93,7 -93,7 +94,7 @@@
  	tree_add_entry (tree, my_s);
  #endif
  
- 	g_free (my_s);
+ 	mhl_mem_free (my_s);
      }
      return result;
  }
@@@ -116,7 -116,7 +117,7 @@@ my_rmdir (const char *s
  	tree_remove_entry (tree, my_s);
  #endif
  
- 	g_free (my_s);
+ 	mhl_mem_free (my_s);
      }
      return result;
  }
diff --combined src/find.c
index 01f75c9,c0d3ed0..bf95b7f
--- a/src/find.c
+++ b/src/find.c
@@@ -27,8 -27,7 +27,9 @@@
  #include <string.h>
  #include <sys/stat.h>
  
 +#include <mhl/types.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -144,7 -143,7 +145,7 @@@ static void get_list_info (char **file
  static regex_t *r; /* Pointer to compiled content_pattern */
   
  static int case_sensitive = 1;
 -static gboolean find_regex_flag = TRUE;
 +static bool find_regex_flag = TRUE;
  static int find_recursively = 1;
  
  /*
@@@ -249,11 -248,11 +250,11 @@@ find_parameters (char **start_dir, cha
  
    find_par_start:
      if (!in_start_dir)
 -	in_start_dir = g_strdup (".");
 +	in_start_dir = mhl_str_dup (".");
      if (!in_start_name)
 -	in_start_name = g_strdup (easy_patterns ? "*" : ".");
 +	in_start_name = mhl_str_dup (easy_patterns ? "*" : ".");
      if (!in_contents)
 -	in_contents = g_strdup ("");
 +	in_contents = mhl_str_dup ("");
  
      find_dlg =
  	create_dlg (0, 0, FIND_Y, FIND_X, dialog_colors,
@@@ -277,16 -276,16 +278,16 @@@
      add_widget (find_dlg, case_sense);
  
      in_with =
 -	input_new (8, istart, INPUT_COLOR, ilen, in_contents, "content");
 +	input_new (8, istart, INPUT_COLOR, ilen, in_contents, "content", INPUT_COMPLETE_DEFAULT);
      add_widget (find_dlg, in_with);
  
      add_widget (find_dlg, recursively_cbox);
      in_name =
 -	input_new (5, istart, INPUT_COLOR, ilen, in_start_name, "name");
 +	input_new (5, istart, INPUT_COLOR, ilen, in_start_name, "name", INPUT_COMPLETE_DEFAULT);
      add_widget (find_dlg, in_name);
  
      in_start =
 -	input_new (3, istart, INPUT_COLOR, ilen, in_start_dir, "start");
 +	input_new (3, istart, INPUT_COLOR, ilen, in_start_dir, "start", INPUT_COMPLETE_DEFAULT);
      add_widget (find_dlg, in_start);
  
      add_widget (find_dlg, label_new (8, 3, labs[2]));
@@@ -303,19 -302,19 +304,19 @@@
  	break;
  
      case B_TREE:
 -	temp_dir = g_strdup (in_start->buffer);
 +	temp_dir = mhl_str_dup (in_start->buffer);
  	case_sensitive = case_sense->state & C_BOOL;
  	find_regex_flag = find_regex_cbox->state & C_BOOL;
   	find_recursively = recursively_cbox->state & C_BOOL;
  	destroy_dlg (find_dlg);
- 	g_free (in_start_dir);
+ 	mhl_mem_free (in_start_dir);
  	if (strcmp (temp_dir, ".") == 0) {
- 	    g_free (temp_dir);
+ 	    mhl_mem_free (temp_dir);
 -	    temp_dir = g_strdup (current_panel->cwd);
 +	    temp_dir = mhl_str_dup (current_panel->cwd);
  	}
  	in_start_dir = tree_box (temp_dir);
  	if (in_start_dir)
- 	    g_free (temp_dir);
+ 	    mhl_mem_free (temp_dir);
  	else
  	    in_start_dir = temp_dir;
  	/* Warning: Dreadful goto */
@@@ -323,10 -322,10 +324,10 @@@
  	break;
  
      default:
- 	g_free (in_contents);
+ 	mhl_mem_free (in_contents);
  	if (in_with->buffer[0]) {
 -	    *content = g_strdup (in_with->buffer);
 -	    in_contents = g_strdup (*content);
 +	    *content = mhl_str_dup (in_with->buffer);
 +	    in_contents = mhl_str_dup (*content);
  	} else {
  	    *content = in_contents = NULL;
  	    r = 0;
@@@ -336,13 -335,13 +337,13 @@@
  	find_regex_flag = find_regex_cbox->state & C_BOOL;
   	find_recursively = recursively_cbox->state & C_BOOL;
  	return_value = 1;
 -	*start_dir = g_strdup (in_start->buffer);
 -	*pattern = g_strdup (in_name->buffer);
 +	*start_dir = mhl_str_dup (in_start->buffer);
 +	*pattern = mhl_str_dup (in_name->buffer);
  
- 	g_free (in_start_dir);
+ 	mhl_mem_free (in_start_dir);
 -	in_start_dir = g_strdup (*start_dir);
 +	in_start_dir = mhl_str_dup (*start_dir);
- 	g_free (in_start_name);
+ 	mhl_mem_free (in_start_name);
 -	in_start_name = g_strdup (*pattern);
 +	in_start_name = mhl_str_dup (*pattern);
      }
  
      destroy_dlg (find_dlg);
@@@ -356,7 -355,7 +357,7 @@@ push_directory (const char *dir
      dir_stack *new;
  
      new = g_new (dir_stack, 1);
 -    new->name = concat_dir_and_file (dir, "");
 +    new->name = mhl_str_dir_plus_file (dir, NULL);
      new->prev = dir_stack_base;
      dir_stack_base = new;
  }
@@@ -370,7 -369,7 +371,7 @@@ pop_directory (void
      if (dir_stack_base){
  	name = dir_stack_base->name;
  	next = dir_stack_base->prev;
- 	g_free (dir_stack_base);
+ 	mhl_mem_free (dir_stack_base);
  	dir_stack_base = next;
  	return name;
      } else
@@@ -388,18 -387,18 +389,18 @@@ insert_file (const char *dir, const cha
  
      if (old_dir){
  	if (strcmp (old_dir, dir)){
- 	    g_free (old_dir);
+ 	    mhl_mem_free (old_dir);
 -	    old_dir = g_strdup (dir);
 +	    old_dir = mhl_str_dup (dir);
  	    dirname = add_to_list (dir, NULL);
  	}
      } else {
 -	old_dir = g_strdup (dir);
 +	old_dir = mhl_str_dup (dir);
  	dirname = add_to_list (dir, NULL);
      }
      
      tmp_name = g_strconcat ("    ", file, (char *) NULL);
      add_to_list (tmp_name, dirname);
-     g_free (tmp_name);
+     mhl_mem_free (tmp_name);
  }
  
  static void
@@@ -518,20 -517,20 +519,20 @@@ search_content (Dlg_head *h, const cha
      int file_fd;
      int ret_val = 0;
  
 -    fname = concat_dir_and_file (directory, filename);
 +    fname = mhl_str_dir_plus_file (directory, filename);
  
      if (mc_stat (fname, &s) != 0 || !S_ISREG (s.st_mode)){
- 	g_free (fname);
+ 	mhl_mem_free (fname);
  	return 0;
      }
  
      file_fd = mc_open (fname, O_RDONLY);
-     g_free (fname);
+     mhl_mem_free (fname);
  
      if (file_fd == -1)
  	return 0;
  
 -    g_snprintf (buffer, sizeof (buffer), _("Grepping in %s"), name_trunc (filename, FIND2_X_USE));
 +    snprintf (buffer, sizeof (buffer), _("Grepping in %s"), name_trunc (filename, FIND2_X_USE));
  
      status_update (buffer);
      mc_refresh ();
@@@ -562,7 -561,7 +563,7 @@@
  	    if (found == 0){	/* Search in binary line once */
  	    	if (find_regex_flag) {
  		if (regexec (r, p, 1, 0, 0) == 0){
- 		    g_free (p);
+ 		    mhl_mem_free (p);
  		    p = g_strdup_printf ("%d:%s", line, filename);
  		    find_add_match (h, directory, p);
  		    found = 1;
@@@ -579,7 -578,7 +580,7 @@@
  		line++;
  		found = 0;
  	    }
- 	    g_free (p);
+ 	    mhl_mem_free (p);
   
   	    if ((line & 0xff) == 0) {
  		FindProgressStatus res;
@@@ -622,7 -621,7 +623,7 @@@ do_search (struct Dlg_head *h
  	    mc_closedir (dirp);
  	    dirp = 0;
  	}
- 	g_free (directory);
+ 	mhl_mem_free (directory);
  	directory = NULL;
          dp = 0;
  	return 1;
@@@ -652,22 -651,22 +653,22 @@@
  		    char *temp_dir = g_strconcat (":", tmp, ":", (char *) NULL);
  
                      found = strstr (find_ignore_dirs, temp_dir) != 0;
-                     g_free (temp_dir);
+                     mhl_mem_free (temp_dir);
  		    if (found)
- 			g_free (tmp);
+ 			mhl_mem_free (tmp);
  		    else
  			break;
  		} else
  		    break;
  	    } 
  
- 	    g_free (directory);
+ 	    mhl_mem_free (directory);
  	    directory = tmp;
  
  	    if (verbose){
  		char buffer [BUF_SMALL];
  
 -		g_snprintf (buffer, sizeof (buffer), _("Searching %s"), 
 +		snprintf (buffer, sizeof (buffer), _("Searching %s"), 
  			    name_trunc (directory, FIND2_X_USE));
  		status_update (buffer);
  	    }
@@@ -694,13 -693,13 +695,13 @@@
      }
  
      if (subdirs_left && find_recursively && directory) { /* Can directory be NULL ? */
 -	char *tmp_name = concat_dir_and_file (directory, dp->d_name);
 +	char *tmp_name = mhl_str_dir_plus_file (directory, dp->d_name);
  	if (!mc_lstat (tmp_name, &tmp_stat)
  	    && S_ISDIR (tmp_stat.st_mode)) {
  	    push_directory (tmp_name);
  	    subdirs_left--;
  	}
- 	g_free (tmp_name);
+ 	mhl_mem_free (tmp_name);
      }
  
      if (regexp_match (find_pattern, dp->d_name, match_file)){
@@@ -737,14 -736,14 +738,14 @@@ init_find_vars (void
  {
      char *dir;
      
-     g_free (old_dir);
+     mhl_mem_free (old_dir);
      old_dir = 0;
      count = 0;
      matches = 0;
  
      /* Remove all the items in the stack */
      while ((dir = pop_directory ()) != NULL)
- 	g_free (dir);
+ 	mhl_mem_free (dir);
  }
  
  static char *
@@@ -752,10 -751,10 +753,10 @@@ make_fullname (const char *dirname, con
  {
  
      if (strcmp(dirname, ".") == 0 || strcmp(dirname, "."PATH_SEP_STR) == 0)
 -	return g_strdup (filename);
 +	return mhl_str_dup (filename);
      if (strncmp(dirname, "."PATH_SEP_STR, 2) == 0)
 -	return concat_dir_and_file (dirname + 2, filename);
 -    return concat_dir_and_file (dirname, filename);
 +	return mhl_str_dir_plus_file (dirname + 2, filename);
 +    return mhl_str_dir_plus_file (dirname, filename);
  }
  
  static void
@@@ -778,7 -777,7 +779,7 @@@ find_do_view_edit (int unparsed_view, i
  	do_edit_at_line (fullname, line);
      else
          view_file_at_line (fullname, unparsed_view, use_internal_view, line);
-     g_free (fullname);
+     mhl_mem_free (fullname);
  }
  
  static int
@@@ -978,14 -977,14 +979,14 @@@ find_file (char *start_dir, char *patte
  
      /* Remove all the items in the stack */
      while ((dir = pop_directory ()) != NULL)
- 	g_free (dir);
+ 	mhl_mem_free (dir);
  
      get_list_info (&file_tmp, &dir_tmp);
  
      if (dir_tmp)
 -	*dirname = g_strdup (dir_tmp);
 +	*dirname = mhl_str_dup (dir_tmp);
      if (file_tmp)
 -	*filename = g_strdup (file_tmp);
 +	*filename = mhl_str_dup (file_tmp);
  
      if (return_value == B_PANELIZE && *filename) {
  	int status, link_to_dir, stale_link;
@@@ -1013,18 -1012,18 +1014,18 @@@
  		handle_path (list, name, &st, next_free, &link_to_dir,
  			     &stale_link);
  	    if (status == 0) {
- 		g_free (name);
+ 		mhl_mem_free (name);
  		continue;
  	    }
  	    if (status == -1) {
- 		g_free (name);
+ 		mhl_mem_free (name);
  		break;
  	    }
  
  	    /* don't add files more than once to the panel */
  	    if (content_pattern && next_free > 0) {
  		if (strcmp (list->list[next_free - 1].fname, name) == 0) {
- 		    g_free (name);
+ 		    mhl_mem_free (name);
  		    continue;
  		}
  	    }
@@@ -1061,7 -1060,7 +1062,7 @@@
  
      kill_gui ();
      do_search (0);		/* force do_search to release resources */
-     g_free (old_dir);
+     mhl_mem_free (old_dir);
      old_dir = 0;
  
      return return_value;
@@@ -1080,8 -1079,8 +1081,8 @@@ do_find (void
  	dirname = filename = NULL;
  	is_start = 0;
  	v = find_file (start_dir, pattern, content, &dirname, &filename);
- 	g_free (start_dir);
- 	g_free (pattern);
+ 	mhl_mem_free (start_dir);
+ 	mhl_mem_free (pattern);
  	if (find_regex_flag && r)
  	    regfree (r);
  	
@@@ -1096,14 -1095,14 +1097,14 @@@
  		    do_cd (filename, cd_exact);
  		select_item (current_panel);
  	    }
- 	    g_free (dirname);
- 	    g_free (filename);
+ 	    mhl_mem_free (dirname);
+ 	    mhl_mem_free (filename);
  	    break;
  	}
- 	g_free (content);
+ 	mhl_mem_free (content);
  	dir_and_file_set = dirname && filename;
- 	g_free (dirname);
- 	g_free (filename);
+ 	mhl_mem_free (dirname);
+ 	mhl_mem_free (filename);
  	if (v == B_CANCEL)
  	    break;
  	
diff --combined src/help.c
index 3c15765,65f2bc3..efdf220
--- a/src/help.c
+++ b/src/help.c
@@@ -48,7 -48,7 +48,8 @@@
  #include <sys/types.h>
  #include <sys/stat.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -105,7 -105,7 +106,7 @@@ static const char 
  search_string (const char *start, const char *text)
  {
      const char *result = NULL;
 -    char *local_text = g_strdup (text);
 +    char *local_text = mhl_str_dup (text);
      char *d = local_text;
      const char *e = start;
  
@@@ -128,7 -128,7 +129,7 @@@
  	}
      }
  cleanup:
-     g_free (local_text);
+     mhl_mem_free (local_text);
      return result;
  }
  
@@@ -328,7 -328,7 +329,7 @@@ static void clear_link_areas (void
      while (link_area){
  	current = link_area;
  	link_area = current -> next;
- 	g_free (current);
+ 	mhl_mem_free (current);
      }
      inside_link_area = 0;
  }
@@@ -754,7 -754,7 +755,7 @@@ static voi
  interactive_display_finish (void)
  {
      clear_link_areas ();
-     g_free (data);
+     mhl_mem_free (data);
  }
  
  void
@@@ -775,7 -775,7 +776,7 @@@ interactive_display (const char *filena
      }
  
      if (!filename)
- 	g_free (hlpfile);
+ 	mhl_mem_free (hlpfile);
  
      if (!data)
  	return;
diff --combined src/hotlist.c
index ef5fc17,559fd0b..a54a0b5
--- a/src/hotlist.c
+++ b/src/hotlist.c
@@@ -36,7 -36,7 +36,8 @@@
  #include <sys/stat.h>
  #include <unistd.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"		/* COLS */
@@@ -200,7 -200,7 +201,7 @@@ update_path_name (void
      else
  	label_set_text (movelist_group,
  			name_trunc (p, dlg->cols - (UX * 2 + 4)));
-     g_free (p);
+     mhl_mem_free (p);
  
      dlg_redraw (dlg);
  }
@@@ -210,7 -210,7 +211,7 @@@ do { 
      int               i; \
  \
      if ((i = strlen (current->label) + 3) > buflen) { \
-       g_free (buf); \
+       mhl_mem_free (buf); \
        buf = g_malloc (buflen = 1024 * (i/1024 + 1)); \
      } \
      buf[0] = '\0'; \
@@@ -464,7 -464,7 +465,7 @@@ hotlist_callback (Dlg_head *h, dlg_msg_
  			    char *tmp =
  				g_strconcat ("cd ", hlp->directory, (char *) NULL);
  			    stuff (cmdline, tmp, 0);
- 			    g_free (tmp);
+ 			    mhl_mem_free (tmp);
  			    dlg_stop (h);
  			    h->ret_value = B_CANCEL;
  			    return MSG_HANDLED;
@@@ -687,7 -687,7 +688,7 @@@ init_movelist (int list_type, struct ho
      movelist_dlg =
  	create_dlg (0, 0, LINES - 6, movelist_cols, dialog_colors,
  		    hotlist_callback, "[Hotlist]", hdr, DLG_CENTER | DLG_REVERSE);
-     g_free (hdr);
+     mhl_mem_free (hdr);
  
      for (i = 0; i < BUTTONS; i++) {
  	if (hotlist_but[i].type & list_type)
@@@ -812,7 -812,7 +813,7 @@@ add2hotlist (char *label, char *directo
  	    char  *lbl = g_strconcat ("->", new->label, (char *) NULL);
  
  	    listbox_add_item (l_hotlist, pos, 0, lbl, new);
- 	    g_free (lbl);
+ 	    mhl_mem_free (lbl);
  	} else
  	    listbox_add_item (l_hotlist, pos, 0, new->label, new);
  	listbox_select_entry (l_hotlist, l_hotlist->current);
@@@ -934,17 -934,17 +935,17 @@@ static void add_new_entry_cmd (void
      int ret;
  
      /* Take current directory as default value for input fields */
 -    to_free = title = url = strip_password (g_strdup (current_panel->cwd), 1);
 +    to_free = title = url = strip_password (mhl_str_dup (current_panel->cwd), 1);
  
      ret = add_new_entry_input (_("New hotlist entry"), _("Directory label"),
  			       _("Directory path"), "[Hotlist]", &title, &url);
-     g_free (to_free);
+     mhl_mem_free (to_free);
  
      if (!ret)
  	return;
      if (!title || !*title || !url || !*url) {
- 	g_free (title);
- 	g_free (url);
+ 	mhl_mem_free (title);
+ 	mhl_mem_free (url);
  	return;
      }
  
@@@ -1039,17 -1039,17 +1040,17 @@@ void add2hotlist_cmd (void
      char *prompt, *label;
      const char *cp = _("Label for \"%s\":");
      int l = strlen (cp);
 -    char *label_string = g_strdup (current_panel->cwd);
 +    char *label_string = mhl_str_dup (current_panel->cwd);
  
      strip_password (label_string, 1);
  
      prompt = g_strdup_printf (cp, path_trunc (current_panel->cwd, COLS-2*UX-(l+8)));
      label = input_dialog (_(" Add to hotlist "), prompt, MC_HISTORY_HOTLIST_ADD, label_string);
-     g_free (prompt);
+     mhl_mem_free (prompt);
  
      if (!label || !*label) {
- 	g_free (label_string);
- 	g_free (label);
+ 	mhl_mem_free (label_string);
+ 	mhl_mem_free (label);
  	return;
      }
      add2hotlist (label, label_string, HL_TYPE_ENTRY, 0);
@@@ -1066,9 -1066,9 +1067,9 @@@ static void remove_group (struct hotlis
  	if (current->type == HL_TYPE_GROUP)
  	    remove_group (current);
  
- 	g_free (current->label);
- 	g_free (current->directory);
- 	g_free (current);
+ 	mhl_mem_free (current->label);
+ 	mhl_mem_free (current->directory);
+ 	mhl_mem_free (current);
  
  	current = next;
      }
@@@ -1095,7 -1095,7 +1096,7 @@@ static void remove_from_hotlist (struc
  			_("\n Are you sure you want to remove this entry?"),
  			D_ERROR, 2, _("&Yes"), _("&No"));
  
- 	g_free (title);
+ 	mhl_mem_free (title);
  
  	if (result != 0)
  	    return;
@@@ -1113,7 -1113,7 +1114,7 @@@
  	    result = query_dialog (header, _("\n Group not empty.\n Remove it?"),
  				   D_ERROR, 2,
  				   _("&Yes"), _("&No"));
- 	    g_free (header);
+ 	    mhl_mem_free (header);
  
  	    if (result != 0)
  		return;
@@@ -1124,9 -1124,9 +1125,9 @@@
  
      unlink_entry (entry);
  
-     g_free (entry->label);
-     g_free (entry->directory);
-     g_free (entry);
+     mhl_mem_free (entry->label);
+     mhl_mem_free (entry->directory);
+     mhl_mem_free (entry);
      /* now remove list entry from screen */
      listbox_remove_current (l_hotlist, 1);
      hotlist_state.modified = 1;
@@@ -1156,9 -1156,9 +1157,9 @@@ char *hotlist_cmd (int vfs_or_hotlist
      case B_ENTER:
  	if (l_hotlist->current->data) {
  	    struct hotlist *hlp = (struct hotlist*) l_hotlist->current->data;
 -	    target = g_strdup (hlp->directory);
 +	    target = mhl_str_dup (hlp->directory);
  	} else
 -	    target = g_strdup (l_hotlist->current->text);
 +	    target = mhl_str_dup (l_hotlist->current->text);
  	break;
      }
  
@@@ -1182,15 -1182,15 +1183,15 @@@ load_group (struct hotlist *grp
  
      while (profile_keys){
  	profile_keys = profile_iterator_next (profile_keys, &key, &value);
 -	add2hotlist (g_strdup (value), g_strdup (key), HL_TYPE_GROUP, 0);
 +	add2hotlist (mhl_str_dup (value), mhl_str_dup (key), HL_TYPE_GROUP, 0);
      }
-     g_free (group_section);
+     mhl_mem_free (group_section);
  
      profile_keys = profile_init_iterator (grp->directory, profile_name);
  
      while (profile_keys){
  	profile_keys = profile_iterator_next (profile_keys, &key, &value);
 -	add2hotlist (g_strdup (value),g_strdup (key), HL_TYPE_ENTRY, 0);
 +	add2hotlist (mhl_str_dup (value),mhl_str_dup (key), HL_TYPE_ENTRY, 0);
      }
  
      for (current = grp->head; current; current = current->next)
@@@ -1332,22 -1332,22 +1333,22 @@@ hot_load_group (struct hotlist * grp
  	switch (tkn) {
  	case TKN_GROUP:
  	    CHECK_TOKEN(TKN_STRING);
 -	    new_grp = add2hotlist (g_strdup (tkn_buf), 0, HL_TYPE_GROUP, 0);
 +	    new_grp = add2hotlist (mhl_str_dup (tkn_buf), 0, HL_TYPE_GROUP, 0);
  	    SKIP_TO_EOL;
  	    hot_load_group (new_grp);
  	    current_group = grp;
  	    break;
  	case TKN_ENTRY:
  	    CHECK_TOKEN(TKN_STRING);
 -	    label = g_strdup (tkn_buf);
 +	    label = mhl_str_dup (tkn_buf);
  	    CHECK_TOKEN(TKN_URL);
  	    CHECK_TOKEN(TKN_STRING);
 -	    url = g_strdup (tkn_buf);
 +	    url = mhl_str_dup (tkn_buf);
  	    add2hotlist (label, url, HL_TYPE_ENTRY, 0);
  	    SKIP_TO_EOL;
  	    break;
  	case TKN_COMMENT:
 -	    label = g_strdup (tkn_buf);
 +	    label = mhl_str_dup (tkn_buf);
  	    add2hotlist (label, 0, HL_TYPE_COMMENT, 0);
  	    break;
  	case TKN_EOF:
@@@ -1380,22 -1380,22 +1381,22 @@@ hot_load_file (struct hotlist * grp
  	switch (tkn) {
  	case TKN_GROUP:
  	    CHECK_TOKEN(TKN_STRING);
 -	    new_grp = add2hotlist (g_strdup (tkn_buf), 0, HL_TYPE_GROUP, 0);
 +	    new_grp = add2hotlist (mhl_str_dup (tkn_buf), 0, HL_TYPE_GROUP, 0);
  	    SKIP_TO_EOL;
  	    hot_load_group (new_grp);
  	    current_group = grp;
  	    break;
  	case TKN_ENTRY:
  	    CHECK_TOKEN(TKN_STRING);
 -	    label = g_strdup (tkn_buf);
 +	    label = mhl_str_dup (tkn_buf);
  	    CHECK_TOKEN(TKN_URL);
  	    CHECK_TOKEN(TKN_STRING);
 -	    url = g_strdup (tkn_buf);
 +	    url = mhl_str_dup (tkn_buf);
  	    add2hotlist (label, url, HL_TYPE_ENTRY, 0);
  	    SKIP_TO_EOL;
  	    break;
  	case TKN_COMMENT:
 -	    label = g_strdup (tkn_buf);
 +	    label = mhl_str_dup (tkn_buf);
  	    add2hotlist (label, 0, HL_TYPE_COMMENT, 0);
  	    break;
  	case TKN_EOL:
@@@ -1428,7 -1428,7 +1429,7 @@@ clean_up_hotlist_groups (const char *se
  	}
  	profile_clean_section (grp_section, profile_name);
      }
-     g_free (grp_section);
+     mhl_mem_free (grp_section);
  }
  
  
@@@ -1448,16 -1448,16 +1449,16 @@@ load_hotlist (void
      }
  
      if (!hotlist_file_name)
 -	hotlist_file_name = concat_dir_and_file (home_dir, HOTLIST_FILENAME);
 +	hotlist_file_name = mhl_str_dir_plus_file (home_dir, HOTLIST_FILENAME);
      
      hotlist	       = new_hotlist ();
      hotlist->type      = HL_TYPE_GROUP;
 -    hotlist->label     = g_strdup (_(" Top level group "));
 +    hotlist->label     = mhl_str_dup (_(" Top level group "));
      hotlist->up        = hotlist;
      /*
       * compatibility :-(
       */
 -    hotlist->directory = g_strdup ("Hotlist");
 +    hotlist->directory = mhl_str_dup ("Hotlist");
  
      if ((hotlist_file = fopen (hotlist_file_name, "r")) == 0) {
  	int	result;
@@@ -1573,7 -1573,7 +1574,7 @@@ int save_hotlist (void
  	    hotlist_state.modified = 0;
  	} else
  	    rename (fbak, hotlist_file_name);
- 	g_free (fbak);
+ 	mhl_mem_free (fbak);
      }
  
      return saved;
@@@ -1587,20 -1587,20 +1588,20 @@@ void done_hotlist (void
  {
      if (hotlist){
  	remove_group (hotlist);
- 	g_free (hotlist->label);
- 	g_free (hotlist->directory);
- 	g_free (hotlist);
+ 	mhl_mem_free (hotlist->label);
+ 	mhl_mem_free (hotlist->directory);
+ 	mhl_mem_free (hotlist);
  	hotlist = 0;
      }
      
      hotlist_state.loaded = 0;
  
-     g_free (hotlist_file_name);
+     mhl_mem_free (hotlist_file_name);
      hotlist_file_name = 0;
      l_hotlist = 0;
      current_group = 0;
      if (tkn_buf){
-         g_free (tkn_buf);
+         mhl_mem_free (tkn_buf);
  	tkn_buf_length = 0;
  	tkn_length = 0;
  	tkn_buf = NULL;
@@@ -1612,6 -1612,6 +1613,6 @@@ add_dotdot_to_list (void
  {
      if (current_group != hotlist) {
  	if (hotlist_has_dot_dot != 0)
 -	    add2hotlist (g_strdup (".."), g_strdup (".."), HL_TYPE_DOTDOT, 0);
 +	    add2hotlist (mhl_str_dup (".."), mhl_str_dup (".."), HL_TYPE_DOTDOT, 0);
      }
  }
diff --combined src/key.c
index 6869091,bd311a3..1434fa7
--- a/src/key.c
+++ b/src/key.c
@@@ -32,8 -32,7 +32,9 @@@
  #include <sys/types.h>
  #include <unistd.h>
  
 +#include <mhl/types.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -154,7 -153,7 +155,7 @@@ void delete_select_channel (int fd
  	    else
  		select_list = p_next;
  
- 	    g_free (p);
+ 	    mhl_mem_free (p);
  	    p = p_next;
  	    continue;
  	}
@@@ -183,7 -182,7 +184,7 @@@ inline static int add_selects (fd_set *
  static void check_selects (fd_set *select_set)
  {
      SelectList *p;
 -    gboolean retry;
 +    bool retry;
  
      if (disabled_channels)
  	return;
@@@ -1234,7 -1233,7 +1235,7 @@@ char *learn_key (void
      keypad(stdscr, TRUE);
      nodelay (stdscr, FALSE);
      *p = 0;
 -    return g_strdup (buffer);
 +    return mhl_str_dup (buffer);
  }
  
  /* xterm and linux console only: set keypad to numeric or application
@@@ -1397,7 -1396,7 +1398,7 @@@ static void k_dispose (key_def *k
  	return;
      k_dispose (k->child);
      k_dispose (k->next);
-     g_free (k);
+     mhl_mem_free (k);
  }
  
  static void s_dispose (SelectList *sel)
@@@ -1406,7 -1405,7 +1407,7 @@@
  	return;
  
      s_dispose (sel->next);
-     g_free (sel);
+     mhl_mem_free (sel);
  }
  
  void done_key ()
diff --combined src/layout.c
index 9e25dea,2df295d..33f58cc
--- a/src/layout.c
+++ b/src/layout.c
@@@ -28,7 -28,6 +28,7 @@@
  #include <string.h>
  #include <sys/types.h>
  #include <sys/stat.h>
 +
       /*
        * If TIOCGWINSZ supported, make it available here, because window-
        * resizing code depends on it...
@@@ -41,7 -40,7 +41,8 @@@
  #endif
  #include <unistd.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"		/* COLS */
@@@ -875,7 -874,7 +876,7 @@@ const char *get_nth_panel_name (int num
      else if (num == 1)
          return "New Right Panel";
      else {
 -        g_snprintf (buffer, sizeof (buffer), "%ith Panel", num);
 +        snprintf (buffer, sizeof (buffer), "%ith Panel", num);
          return buffer;
      }
  }
@@@ -1052,14 -1051,14 +1053,14 @@@ void swap_panels (
  	
  	if (panels [0].type == view_listing) {
              if (!strcmp (panel1->panel_name, get_nth_panel_name (0))) {
-                 g_free (panel1->panel_name);
+                 mhl_mem_free (panel1->panel_name);
 -                panel1->panel_name = g_strdup (get_nth_panel_name (1));
 +                panel1->panel_name = mhl_str_dup (get_nth_panel_name (1));
              }
          }
          if (panels [1].type == view_listing) {
              if (!strcmp (panel2->panel_name, get_nth_panel_name (1))) {
-                 g_free (panel2->panel_name);
+                 mhl_mem_free (panel2->panel_name);
 -                panel2->panel_name = g_strdup (get_nth_panel_name (0));
 +                panel2->panel_name = mhl_str_dup (get_nth_panel_name (0));
              }
          }
          
diff --combined src/learn.c
index 9320883,6499b8f..2be4b8c
--- a/src/learn.c
+++ b/src/learn.c
@@@ -25,11 -25,12 +25,12 @@@
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
- 
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <unistd.h>
  
+ #include <mhl/memory.h>
+ 
  #include "global.h"
  #include "tty.h"
  #include "win.h"
@@@ -88,7 -89,7 +89,7 @@@ _("Please press the %s\n
          _(key_name_conv_tab [action - B_USER].longname));
      mc_refresh ();
      if (learnkeys [action - B_USER].sequence != NULL) {
- 	g_free (learnkeys [action - B_USER].sequence);
+ 	mhl_mem_free (learnkeys [action - B_USER].sequence);
  	learnkeys [action - B_USER].sequence = NULL;
      }
      seq = learn_key ();
@@@ -117,7 -118,7 +118,7 @@@
  		_(" You have entered \"%s\""), seq);
  	}
  	
-     	g_free (seq);
+     	mhl_mem_free (seq);
      }
      
      dlg_run_done (d);
@@@ -270,7 -271,7 +271,7 @@@ init_learn (void
      for (i = j - 1, key = key_name_conv_tab + j - 1; i >= 0; i--, key--) {
  	learnkeys[i].ok = 0;
  	learnkeys[i].sequence = NULL;
 -	g_snprintf (buffer, sizeof (buffer), "%-16s", _(key->longname));
 +	snprintf (buffer, sizeof (buffer), "%-16s", _(key->longname));
  	add_widget (learn_dlg, learnkeys[i].button = (Widget *)
  		    button_new (y, x, B_USER + i, NARROW_BUTTON, buffer,
  				learn_button));
@@@ -327,7 -328,7 +328,7 @@@ learn_save (void
      if (profile_changed)
  	sync_profiles ();
  
-     g_free (section);
+     mhl_mem_free (section);
  }
  
  void learn_keys (void)
diff --combined src/listmode.c
index 84af113,26de21b..0cfcbf6
--- a/src/listmode.c
+++ b/src/listmode.c
@@@ -26,12 -26,11 +26,12 @@@
  
  #include <stdio.h>
  #include <string.h>
 -
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <unistd.h>
  
 +#include <mhl/string.h>
 +
  #include "global.h"
  #include "tty.h"
  #include "win.h"
@@@ -288,9 -287,9 +288,9 @@@ listmode_edit (char *oldlistformat
      char *s;
      Dlg_head *listmode_dlg;
  
 -    s = g_strdup (oldlistformat);
 +    s = mhl_str_dup (oldlistformat);
      listmode_dlg = init_listmode (s);
-     g_free (s);
+     mhl_mem_free (s);
  
      if (run_dlg (listmode_dlg) == B_ENTER) {
  	newformat = collect_new_format ();
diff --combined src/logging.c
index 9fa8605,a13b8ba..a48dcfb
--- a/src/logging.c
+++ b/src/logging.c
@@@ -26,7 -26,7 +26,8 @@@
  #include <stdarg.h>
  #include <stdio.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/types.h>
  
  #include "global.h"
  #include "logging.h"
@@@ -34,18 -34,18 +35,18 @@@
  
  /*** file scope functions **********************************************/
  
 -static gboolean
 +static bool
  is_logging_enabled(void)
  {
 -	static gboolean logging_initialized = FALSE;
 -	static gboolean logging_enabled = FALSE;
 +	static bool logging_initialized = FALSE;
 +	static bool logging_enabled = FALSE;
  	char *mc_ini;
  
  	if (!logging_initialized) {
  		mc_ini = g_strdup_printf("%s/%s", home_dir, PROFILE_NAME);
  		logging_enabled =
  		    get_int(mc_ini, "development.enable_logging", FALSE);
- 		g_free(mc_ini);
+ 		mhl_mem_free(mc_ini);
  		logging_initialized = TRUE;
  	}
  	return logging_enabled;
@@@ -67,6 -67,6 +68,6 @@@ mc_log(const char *fmt, ...
  			(void)vfprintf(f, fmt, args);
  			(void)fclose(f);
  		}
- 		g_free(logfilename);
+ 		mhl_mem_free(logfilename);
  	}
  }
diff --combined src/main.c
index 6c867a5,5f5461b..6a8376a
--- a/src/main.c
+++ b/src/main.c
@@@ -33,7 -33,7 +33,8 @@@
  #include <sys/stat.h>
  #include <unistd.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -67,6 -67,7 +68,6 @@@
  #include "widget.h"
  #include "command.h"
  #include "wtools.h"
 -#include "complete.h"		/* For the free_completion */
  
  #include "chmod.h"
  #include "chown.h"
@@@ -301,7 -302,7 +302,7 @@@ reload_panelized (WPanel *panel
  	    do_file_mark (panel, i, 0);
  	}
  	if (mc_lstat (list->list[i].fname, &list->list[i].st)) {
- 	    g_free (list->list[i].fname);
+ 	    mhl_mem_free (list->list[i].fname);
  	    continue;
  	}
  	if (list->list[i].f.marked)
@@@ -335,7 -336,7 +336,7 @@@ update_one_panel_widget (WPanel *panel
      /* If current_file == -1 (an invalid pointer) then preserve selection */
      if (current_file == UP_KEEPSEL) {
  	free_pointer = 1;
 -	my_current_file = g_strdup (panel->dir.list[panel->selected].fname);
 +	my_current_file = mhl_str_dup (panel->dir.list[panel->selected].fname);
  	current_file = my_current_file;
      } else
  	free_pointer = 0;
@@@ -349,7 -350,7 +350,7 @@@
      panel->dirty = 1;
  
      if (free_pointer)
- 	g_free (my_current_file);
+ 	mhl_mem_free (my_current_file);
  }
  
  void
@@@ -532,7 -533,7 +533,7 @@@ directory_history_add (struct WPanel *p
  {
      char *tmp;
  
 -    tmp = g_strdup (dir);
 +    tmp = mhl_str_dup (dir);
      strip_password (tmp, 1);
  
      panel->dir_history = list_append_unique (panel->dir_history, tmp);
@@@ -574,7 -575,7 +575,7 @@@ _do_panel_cd (WPanel *panel, const cha
  	    new_dir++;
      }
  
 -    olddir = g_strdup (panel->cwd);
 +    olddir = mhl_str_dup (panel->cwd);
      new_dir = translated_url = vfs_translate_url (new_dir);
  
      /* Convert *new_path to a suitable pathname, handle ~user */
@@@ -589,11 -590,11 +590,11 @@@
  
      if (mc_chdir (directory) == -1) {
  	strcpy (panel->cwd, olddir);
- 	g_free (olddir);
- 	g_free (translated_url);
+ 	mhl_mem_free (olddir);
+ 	mhl_mem_free (translated_url);
  	return 0;
      }
-     g_free (translated_url);
+     mhl_mem_free (translated_url);
  
      /* Success: save previous directory, shutdown status of previous dir */
      strcpy (panel->lwd, olddir);
@@@ -616,7 -617,7 +617,7 @@@
      panel->dirty = 1;
      update_xterm_title_path ();
  
-     g_free (olddir);
+     mhl_mem_free (olddir);
  
      return 1;
  }
@@@ -687,7 -688,7 +688,7 @@@ directory_history_list (WPanel *panel
  	directory_history_add (panel, panel->cwd);
      else
  	message (D_ERROR, MSG_ERROR, _("Cannot change directory"));
-     g_free (s);
+     mhl_mem_free (s);
  }
  
  #ifdef HAVE_SUBSHELL_SUPPORT
@@@ -776,7 -777,7 +777,7 @@@ treebox_cmd (void
      sel_dir = tree_box (selection (current_panel)->fname);
      if (sel_dir) {
  	do_cd (sel_dir, cd_exact);
- 	g_free (sel_dir);
+ 	mhl_mem_free (sel_dir);
      }
  }
  
@@@ -793,7 -794,7 +794,7 @@@ listmode_cmd (void
      if (!newmode)
  	return;
  
-     g_free (current_panel->user_format);
+     mhl_mem_free (current_panel->user_format);
      current_panel->list_type = list_user;
      current_panel->user_format = newmode;
      set_panel_formats (current_panel);
@@@ -1035,7 -1036,7 +1036,7 @@@ translated_mc_chdir (char *dir
  
      newdir = vfs_translate_url (dir);
      mc_chdir (newdir);
-     g_free (newdir);
+     mhl_mem_free (newdir);
  }
  
  static void
@@@ -1137,11 -1138,11 +1138,11 @@@ copy_readlink (WPanel *panel
      if (S_ISLNK (selection (panel)->st.st_mode)) {
  	char buffer[MC_MAXPATHLEN];
  	char *p =
 -	    concat_dir_and_file (panel->cwd, selection (panel)->fname);
 +	    mhl_str_dir_plus_file (panel->cwd, selection (panel)->fname);
  	int i;
  
  	i = mc_readlink (p, buffer, MC_MAXPATHLEN - 1);
- 	g_free (p);
+ 	mhl_mem_free (p);
  	if (i > 0) {
  	    buffer[i] = 0;
  	    command_insert (cmdline, buffer, 1);
@@@ -1612,7 -1613,7 +1613,7 @@@ update_xterm_title_path (void
      char *p, *s;
  
      if (xterm_flag && xterm_title) {
 -	p = s = g_strdup (strip_home_and_password (current_panel->cwd));
 +	p = s = mhl_str_dup (strip_home_and_password (current_panel->cwd));
  	do {
  	    if (!is_printable ((unsigned char) *s))
  		*s = '?';
@@@ -1621,7 -1622,7 +1622,7 @@@
  	    numeric_keypad_mode ();
  	fprintf (stdout, "\33]0;mc - %s\7", p);
  	fflush (stdout);
- 	g_free (p);
+ 	mhl_mem_free (p);
      }
  }
  
@@@ -1645,11 -1646,11 +1646,11 @@@ load_hint (int force
      if ((hint = get_random_hint (force))) {
  	if (*hint)
  	    set_hintbar (hint);
- 	g_free (hint);
+ 	mhl_mem_free (hint);
      } else {
  	char text[BUF_SMALL];
  
 -	g_snprintf (text, sizeof (text), _("GNU Midnight Commander %s\n"),
 +	snprintf (text, sizeof (text), _("GNU Midnight Commander %s\n"),
  		    VERSION);
  	set_hintbar (text);
      }
@@@ -1686,7 -1687,7 +1687,7 @@@ prepend_cwd_on_local (const char *filen
  
      if (vfs_file_is_local (filename)) {
  	if (*filename == PATH_SEP)	/* an absolute pathname */
 -	    return g_strdup (filename);
 +	    return mhl_str_dup (filename);
  	d = g_malloc (MC_MAXPATHLEN + strlen (filename) + 2);
  	mc_get_current_wd (d, MC_MAXPATHLEN);
  	l = strlen (d);
@@@ -1695,7 -1696,7 +1696,7 @@@
  	canonicalize_pathname (d);
  	return d;
      } else
 -	return g_strdup (filename);
 +	return mhl_str_dup (filename);
  }
  
  static int
@@@ -1713,7 -1714,7 +1714,7 @@@ mc_maybe_editor_or_viewer (void
  	char *path = NULL;
  	path = prepend_cwd_on_local (view_one_file);
  	view_file (path, 0, 1);
- 	g_free (path);
+ 	mhl_mem_free (path);
      }
  #ifdef USE_INTERNAL_EDIT
      else {
@@@ -1753,7 -1754,7 +1754,7 @@@ do_nc (void
  
      /* destroy_dlg destroys even current_panel->cwd, so we have to save a copy :) */
      if (last_wd_file && vfs_current_is_local ()) {
 -	last_wd_string = g_strdup (current_panel->cwd);
 +	last_wd_string = mhl_str_dup (current_panel->cwd);
      }
      done_mc ();
  
@@@ -1772,7 -1773,7 +1773,7 @@@ OS_Setup (void
          struct passwd *pwd;
          pwd = getpwuid (geteuid ());
          if (pwd != NULL)
 -           shell = g_strdup (pwd->pw_shell);
 +           shell = mhl_str_dup (pwd->pw_shell);
      }
      if (!shell || !*shell)
  	shell = "/bin/sh";
@@@ -1780,9 -1781,9 +1781,9 @@@
      /* This is the directory, where MC was installed, on Unix this is DATADIR */
      /* and can be overriden by the MC_DATADIR environment variable */
      if ((mc_libdir = getenv ("MC_DATADIR")) != NULL) {
 -	mc_home = g_strdup (mc_libdir);
 +	mc_home = mhl_str_dup (mc_libdir);
      } else {
 -	mc_home = g_strdup (DATADIR);
 +	mc_home = mhl_str_dup (DATADIR);
      }
  }
  
@@@ -2082,7 -2083,7 +2083,7 @@@ handle_args (int argc, char *argv[]
  		    edit_one_file = fname;
  		    edit_one_file_start_line = atoi (p);
  		} else {
- 		    g_free (fname);
+ 		    mhl_mem_free (fname);
  		    goto try_plus_filename;
  		}
  	    } else {
@@@ -2097,12 -2098,12 +2098,12 @@@
  			}
  		    }
  		}
 -		edit_one_file = g_strdup (tmp);
 +		edit_one_file = mhl_str_dup (tmp);
  	    }
  	}
      } else if (!STRNCOMP (base, "mcv", 3) || !STRCOMP (base, "view")) {
  	if (tmp)
 -	    view_one_file = g_strdup (tmp);
 +	    view_one_file = mhl_str_dup (tmp);
  	else {
  	    fputs ("No arguments given to the viewer\n", stderr);
  	    exit (1);
@@@ -2110,9 -2111,9 +2111,9 @@@
      } else {
  	/* sets the current dir and the other dir */
  	if (tmp) {
 -	    this_dir = g_strdup (tmp);
 +	    this_dir = mhl_str_dup (tmp);
  	    if ((tmp = poptGetArg (ctx)))
 -		other_dir = g_strdup (tmp);
 +		other_dir = mhl_str_dup (tmp);
  	}
      }
  
@@@ -2251,15 -2252,15 +2252,15 @@@ main (int argc, char *argv[]
  	    close (last_wd_fd);
  	}
      }
-     g_free (last_wd_string);
+     mhl_mem_free (last_wd_string);
  
-     g_free (mc_home);
+     mhl_mem_free (mc_home);
      done_key ();
  #ifdef HAVE_CHARSET
      free_codepages_list ();
  #endif
-     g_free (this_dir);
-     g_free (other_dir);
+     mhl_mem_free (this_dir);
+     mhl_mem_free (other_dir);
  
      return 0;
  }
diff --combined src/menu.c
index 41bda66,b61df7c..09e91e3
--- a/src/menu.c
+++ b/src/menu.c
@@@ -23,7 -23,7 +23,8 @@@
  #include <string.h>
  #include <sys/types.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -82,10 -82,10 +83,10 @@@ create_menu (const char *name, menu_ent
  	}
      }
  
 -    menu->name = g_strdup (name);
 +    menu->name = mhl_str_dup (name);
      menu_scan_hotkey(menu);
      menu->start_x = 0;
 -    menu->help_node = g_strdup (help_node);
 +    menu->help_node = mhl_str_dup (help_node);
      return menu;
  }
  
@@@ -532,9 -532,9 +533,9 @@@ menubar_arrange(WMenu* menubar
  void
  destroy_menu (Menu *menu)
  {
-     g_free (menu->name);
-     g_free (menu->help_node);
-     g_free (menu);
+     mhl_mem_free (menu->name);
+     mhl_mem_free (menu->help_node);
+     mhl_mem_free (menu);
  }
  
  WMenu *
diff --combined src/panelize.c
index 28a62c0,d02f4cd..b2902d2
--- a/src/panelize.c
+++ b/src/panelize.c
@@@ -29,7 -29,7 +29,8 @@@
  #include <sys/stat.h>
  #include <unistd.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"		/* attrset() */
@@@ -166,7 -166,7 +167,7 @@@ init_panelize (void
  
      pname =
  	input_new (UY + 14, UX, INPUT_COLOR, panelize_dlg->cols - 10, "",
 -		   "in");
 +		   "in", INPUT_COMPLETE_DEFAULT);
      add_widget (panelize_dlg, pname);
  
      add_widget (panelize_dlg, label_new (UY + 13, UX, _("Command")));
@@@ -233,11 -233,11 +234,11 @@@ add2panelize_cmd (void
  	if (!label)
  	    return;
  	if (!*label) {
- 	    g_free (label);
+ 	    mhl_mem_free (label);
  	    return;
  	}
  	
 -	add2panelize (label, g_strdup (pname->buffer));
 +	add2panelize (label, mhl_str_dup (pname->buffer));
      }
  }
  
@@@ -255,9 -255,9 +256,9 @@@ static void remove_from_panelize (struc
  	    }
  	}
  
- 	g_free (entry->label);
- 	g_free (entry->command);
- 	g_free (entry);
+ 	mhl_mem_free (entry->label);
+ 	mhl_mem_free (entry->command);
+ 	mhl_mem_free (entry);
      }
  }
  
@@@ -294,10 -294,10 +295,10 @@@ external_panelize (void
      case B_ENTER:
  	target = pname->buffer;
  	if (target != NULL && *target) {
 -	    char *cmd = g_strdup (target);
 +	    char *cmd = mhl_str_dup (target);
  	    destroy_dlg (panelize_dlg);
  	    do_external_panelize (cmd);
- 	    g_free (cmd);
+ 	    mhl_mem_free (cmd);
  	    repaint_screen ();
  	    return;
  	}
@@@ -314,18 -314,18 +315,18 @@@ void load_panelize (void
      
      profile_keys = profile_init_iterator (panelize_section, profile_name);
      
 -    add2panelize (g_strdup (_("Other command")), g_strdup (""));
 +    add2panelize (mhl_str_dup (_("Other command")), mhl_str_dup (""));
  
      if (!profile_keys){
 -	add2panelize (g_strdup (_("Find rejects after patching")), g_strdup ("find . -name \\*.rej -print"));
 -	add2panelize (g_strdup (_("Find *.orig after patching")), g_strdup ("find . -name \\*.orig -print"));
 -	add2panelize (g_strdup (_("Find SUID and SGID programs")), g_strdup ("find . \\( \\( -perm -04000 -a -perm +011 \\) -o \\( -perm -02000 -a -perm +01 \\) \\) -print"));
 +	add2panelize (mhl_str_dup (_("Find rejects after patching")), mhl_str_dup ("find . -name \\*.rej -print"));
 +	add2panelize (mhl_str_dup (_("Find *.orig after patching")), mhl_str_dup ("find . -name \\*.orig -print"));
 +	add2panelize (mhl_str_dup (_("Find SUID and SGID programs")), mhl_str_dup ("find . \\( \\( -perm -04000 -a -perm +011 \\) -o \\( -perm -02000 -a -perm +01 \\) \\) -print"));
  	return;
      }
      
      while (profile_keys){
  	profile_keys = profile_iterator_next (profile_keys, &key, &value);
 -	add2panelize (g_strdup (key), g_strdup (value));
 +	add2panelize (mhl_str_dup (key), mhl_str_dup (value));
      }
  }
  
@@@ -351,9 -351,9 +352,9 @@@ void done_panelize (void
  
      for (; current; current = next){
  	next = current->next;
- 	g_free (current->label);
- 	g_free (current->command);
- 	g_free (current);
+ 	mhl_mem_free (current->label);
+ 	mhl_mem_free (current->command);
+ 	mhl_mem_free (current);
      }
  }
  
@@@ -399,7 -399,7 +400,7 @@@ static void do_external_panelize (char 
  	if (status == -1)
  	    break;
  	list->list [next_free].fnamelen = strlen (name);
 -	list->list [next_free].fname = g_strdup (name);
 +	list->list [next_free].fname = mhl_str_dup (name);
  	file_mark (current_panel, next_free, 0);
  	list->list [next_free].f.link_to_dir = link_to_dir;
  	list->list [next_free].f.stale_link = stale_link;
diff --combined src/profile.c
index 6b27d63,fd6a0d5..7ae367b
--- a/src/profile.c
+++ b/src/profile.c
@@@ -28,7 -28,7 +28,8 @@@
  #include <string.h>
  #include <sys/types.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "profile.h"
@@@ -169,7 -169,7 +170,7 @@@ static TSecHeader *load (const char *fi
  	    if (c == ']' || overflow){
  		*next = '\0';
  		next = CharBuffer;
 -		SecHeader->AppName = g_strdup (CharBuffer);
 +		SecHeader->AppName = mhl_str_dup (CharBuffer);
  		state = IgnoreToEOL;
  	    } else
  		*next++ = c;
@@@ -215,7 -215,7 +216,7 @@@
  		*next = '\0';
  		SecHeader->Keys =g_new (TKeys, 1);
  		SecHeader->Keys->link = temp;
 -		SecHeader->Keys->KeyName = g_strdup (CharBuffer);
 +		SecHeader->Keys->KeyName = mhl_str_dup (CharBuffer);
  		state = KeyValue;
  		next = CharBuffer;
  	    } else {
@@@ -249,7 -249,7 +250,7 @@@
  	break;
      case OnSecHeader: {		/* Broken initialization file */
  	    TSecHeader *link = SecHeader->link;
- 	    g_free (SecHeader);
+ 	    mhl_mem_free (SecHeader);
  	    SecHeader = link;
  	    fprintf (stderr, "Warning: Corrupted initialization file `%s'\n",
  		     file);
@@@ -266,8 -266,8 +267,8 @@@ static void new_key (TSecHeader *sectio
      TKeys *key;
      
      key = g_new (TKeys, 1);
 -    key->KeyName = g_strdup (KeyName);
 -    key->Value   = g_strdup (Value);
 +    key->KeyName = mhl_str_dup (KeyName);
 +    key->Value   = mhl_str_dup (Value);
      key->link = section->Keys;
      section->Keys = key;
  }
@@@ -285,7 -285,7 +286,7 @@@ GetSetProfileChar (int set, const char 
      if (!Current) {
  	Current = g_new (TProfile, 1);
  	Current->link = Base;
 -	Current->FileName = g_strdup (FileName);
 +	Current->FileName = mhl_str_dup (FileName);
  	Current->Section = load (FileName);
  	Base = Current;
  	section = Current->Section;
@@@ -299,8 -299,8 +300,8 @@@
  	    if ( g_strcasecmp (key->KeyName, KeyName))
  		continue;
  	    if (set){
- 		g_free (key->Value);
+ 		mhl_mem_free (key->Value);
 -		key->Value = g_strdup (Default);
 +		key->Value = mhl_str_dup (Default);
  	    }
  	    return key->Value;
  	}
@@@ -316,7 -316,7 +317,7 @@@
      /* Non existent section */
      if (set && Default){
  	section = g_new (TSecHeader, 1);
 -	section->AppName = g_strdup (AppName);
 +	section->AppName = mhl_str_dup (AppName);
  	section->Keys = 0;
  	new_key (section, KeyName, Default);
  	section->link = Current->Section;
@@@ -358,7 -358,7 +359,7 @@@ int GetPrivateProfileInt (const char * 
      char IntBuf [BUF_TINY];
      char buf [BUF_TINY];
  
 -    g_snprintf (buf, sizeof (buf), "%d", Default);
 +    snprintf (buf, sizeof (buf), "%d", Default);
      
      /* Check the exact semantic with the SDK */
      GetPrivateProfileString (AppName, KeyName, buf, IntBuf, BUF_TINY, File);
@@@ -383,7 -383,7 +384,7 @@@ static void dump_keys (FILE * profile, 
      dump_keys (profile, p->link);
      t = str_untranslate_newline_dup (p->Value);
      fprintf (profile, "%s=%s\n", p->KeyName, t);
-     g_free (t);
+     mhl_mem_free (t);
  }
  
  static void dump_sections (FILE *profile, TSecHeader *p)
@@@ -426,9 -426,9 +427,9 @@@ static void free_keys (TKeys *p
      if (!p)
  	return;
      free_keys (p->link);
-     g_free (p->KeyName);
-     g_free (p->Value);
-     g_free (p);
+     mhl_mem_free (p->KeyName);
+     mhl_mem_free (p->Value);
+     mhl_mem_free (p);
  }
  
  static void free_sections (TSecHeader *p)
@@@ -437,10 -437,10 +438,10 @@@
  	return;
      free_sections (p->link);
      free_keys (p->Keys);
-     g_free (p->AppName);
+     mhl_mem_free (p->AppName);
      p->link = 0;
      p->Keys = 0;
-     g_free (p);
+     mhl_mem_free (p);
  }
  
  static void free_profile (TProfile *p)
@@@ -449,8 -449,8 +450,8 @@@
  	return;
      free_profile (p->link);
      free_sections (p->Section);
-     g_free (p->FileName);
-     g_free (p);
+     mhl_mem_free (p->FileName);
+     mhl_mem_free (p);
  }
  
  void free_profile_name (const char *s)
@@@ -484,7 -484,7 +485,7 @@@ void *profile_init_iterator (const cha
      if (!Current) {
  	Current = g_new (TProfile, 1);
  	Current->link = Base;
 -	Current->FileName = g_strdup (file);
 +	Current->FileName = mhl_str_dup (file);
  	Current->Section = load (file);
  	Base = Current;
  	section = Current->Section;
diff --combined src/screen.c
index 7a6683a,8921e39..b2d5697
--- a/src/screen.c
+++ b/src/screen.c
@@@ -27,7 -27,7 +27,8 @@@
  #include <string.h>
  #include <unistd.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -132,7 -132,7 +133,7 @@@ delete_format (format_e *format
  
      while (format){
          next = format->next;
-         g_free (format);
+         mhl_mem_free (format);
          format = next;
       }
  }
@@@ -212,7 -212,7 +213,7 @@@ static void format_device_number (char 
  
      g_assert(bufsize >= 1);
      if (major_digits + 1 + minor_digits + 1 <= bufsize) {
 -        g_snprintf(buf, bufsize, "%lu,%lu", (unsigned long) major_dev,
 +        snprintf(buf, bufsize, "%lu,%lu", (unsigned long) major_dev,
                     (unsigned long) minor_dev);
      } else {
          g_strlcpy(buf, _("[dev]"), bufsize);
@@@ -337,7 -337,7 +338,7 @@@ string_file_perm_octal (file_entry *fe
  {
      static char buffer [10];
  
 -    g_snprintf (buffer, sizeof (buffer), "0%06lo", (unsigned long) fe->st.st_mode);
 +    snprintf (buffer, sizeof (buffer), "0%06lo", (unsigned long) fe->st.st_mode);
      return buffer;
  }
  
@@@ -347,7 -347,7 +348,7 @@@ string_file_nlinks (file_entry *fe, in
  {
      static char buffer[BUF_TINY];
  
 -    g_snprintf (buffer, sizeof (buffer), "%16d", (int) fe->st.st_nlink);
 +    snprintf (buffer, sizeof (buffer), "%16d", (int) fe->st.st_nlink);
      return buffer;
  }
  
@@@ -357,7 -357,7 +358,7 @@@ string_inode (file_entry *fe, int len
  {
      static char buffer [10];
  
 -    g_snprintf (buffer, sizeof (buffer), "%lu",
 +    snprintf (buffer, sizeof (buffer), "%lu",
  		(unsigned long) fe->st.st_ino);
      return buffer;
  }
@@@ -368,7 -368,7 +369,7 @@@ string_file_nuid (file_entry *fe, int l
  {
      static char buffer [10];
  
 -    g_snprintf (buffer, sizeof (buffer), "%lu",
 +    snprintf (buffer, sizeof (buffer), "%lu",
  		(unsigned long) fe->st.st_uid);
      return buffer;
  }
@@@ -379,7 -379,7 +380,7 @@@ string_file_ngid (file_entry *fe, int l
  {
      static char buffer [10];
  
 -    g_snprintf (buffer, sizeof (buffer), "%lu",
 +    snprintf (buffer, sizeof (buffer), "%lu",
  		(unsigned long) fe->st.st_gid);
      return buffer;
  }
@@@ -686,11 -686,11 +687,11 @@@ display_mini_info (WPanel *panel
  	 * This is a trick to use two ngettext() calls in one sentence.
  	 * First make "N bytes", then insert it into "X in M files".
  	 */
 -	g_snprintf(b_bytes, sizeof (b_bytes),
 +	snprintf(b_bytes, sizeof (b_bytes),
  		   ngettext("%s byte", "%s bytes",
  			    (unsigned long)panel->total),
  		   size_trunc_sep(panel->total));
 -	g_snprintf(buffer, sizeof (buffer),
 +	snprintf(buffer, sizeof (buffer),
  		   ngettext("%s in %d file", "%s in %d files", panel->marked),
  		   b_bytes, panel->marked);
  
@@@ -710,9 -710,9 +711,9 @@@
  	char *link, link_target [MC_MAXPATHLEN];
  	int  len;
  
 -	link = concat_dir_and_file (panel->cwd, panel->dir.list [panel->selected].fname);
 +	link = mhl_str_dir_plus_file (panel->cwd, panel->dir.list [panel->selected].fname);
  	len = mc_readlink (link, link_target, MC_MAXPATHLEN - 1);
- 	g_free (link);
+ 	mhl_mem_free (link);
  	if (len > 0){
  	    link_target[len] = 0;
  	    tty_printf ("-> %-*s", panel->widget.cols - 5,
@@@ -797,7 -797,7 +798,7 @@@ show_dir (WPanel *panel
      trim (strip_home_and_password (panel->cwd), tmp,
  	 max (panel->widget.cols - 9, 0));
      addstr (tmp);
-     g_free (tmp);
+     mhl_mem_free (tmp);
  
      addch (' ');
      widget_move (&panel->widget, 0, 1);
@@@ -893,7 -893,7 +894,7 @@@ do_try_to_select (WPanel *panel, const 
      for (i = 0; i < panel->count; i++){
  	if (strcmp (subdir, panel->dir.list [i].fname) == 0) {
  	    do_select (panel, i);
-             g_free (subdir);
+             mhl_mem_free (subdir);
  	    return;
          }
      }
@@@ -901,7 -901,7 +902,7 @@@
      /* Try to select a file near the file that is missing */
      if (panel->selected >= panel->count)
          do_select (panel, panel->count-1);
-     g_free (subdir);
+     mhl_mem_free (subdir);
  }
  
  void
@@@ -945,7 -945,7 +946,7 @@@ panel_save_name (WPanel *panel
  
      /* If the program is shuting down */
      if ((midnight_shutdown && auto_save_setup) || saving_setup)
 -	return  g_strdup (panel->panel_name);
 +	return  mhl_str_dup (panel->panel_name);
      else
  	return  g_strconcat ("Temporal:", panel->panel_name, (char *) NULL);
  }
@@@ -965,21 -965,21 +966,21 @@@ panel_destroy (WPanel *p
  	history_put (p->hist_name, p->dir_history);
  
  	p->dir_history = g_list_first (p->dir_history);
- 	g_list_foreach (p->dir_history, (GFunc) g_free, NULL);
+ 	g_list_foreach (p->dir_history, (GFunc) mhl_mem_free, NULL);
  	g_list_free (p->dir_history);
      }
  
-     g_free (p->hist_name);
+     mhl_mem_free (p->hist_name);
  
      delete_format (p->format);
      delete_format (p->status_format);
  
-     g_free (p->user_format);
+     mhl_mem_free (p->user_format);
      for (i = 0; i < LIST_TYPES; i++)
- 	g_free (p->user_status_format[i]);
-     g_free (p->dir.list);
-     g_free (p->panel_name);
-     g_free (name);
+ 	mhl_mem_free (p->user_status_format[i]);
+     mhl_mem_free (p->dir.list);
+     mhl_mem_free (p->panel_name);
+     mhl_mem_free (name);
  }
  
  static void
@@@ -1030,21 -1030,21 +1031,21 @@@ panel_new (const char *panel_name
      panel->status_format = 0;
      panel->format_modified = 1;
  
 -    panel->panel_name = g_strdup (panel_name);
 -    panel->user_format = g_strdup (DEFAULT_USER_FORMAT);
 +    panel->panel_name = mhl_str_dup (panel_name);
 +    panel->user_format = mhl_str_dup (DEFAULT_USER_FORMAT);
  
      for (i = 0; i < LIST_TYPES; i++)
 -	panel->user_status_format[i] = g_strdup (DEFAULT_USER_FORMAT);
 +	panel->user_status_format[i] = mhl_str_dup (DEFAULT_USER_FORMAT);
  
      panel->search_buffer[0] = 0;
      panel->frame_size = frame_half;
      section = g_strconcat ("Temporal:", panel->panel_name, (char *) NULL);
      if (!profile_has_section (section, profile_name)) {
- 	g_free (section);
+ 	mhl_mem_free (section);
 -	section = g_strdup (panel->panel_name);
 +	section = mhl_str_dup (panel->panel_name);
      }
      panel_load_setup (panel, section);
-     g_free (section);
+     mhl_mem_free (section);
  
      /* Load format strings */
      err = set_panel_formats (panel);
@@@ -1321,13 -1321,13 +1322,13 @@@ parse_display_format (WPanel *panel, co
  	    break;
  	}
  	if (!found){
 -	    char *tmp_format = g_strdup (format);
 +	    char *tmp_format = mhl_str_dup (format);
  
  	    int pos = min (8, strlen (format));
  	    delete_format (home);
  	    tmp_format [pos] = 0;
  	    *error = g_strconcat (_("Unknown tag on display format: "), tmp_format, (char *) NULL);
- 	    g_free (tmp_format);
+ 	    mhl_mem_free (tmp_format);
  	    return 0;
  	}
  	total_cols += darr->requested_field_len;
@@@ -1416,7 -1416,7 +1417,7 @@@ set_panel_formats (WPanel *p
      form = use_display_format (p, panel_format (p), &err, 0);
  
      if (err){
-         g_free (err);
+         mhl_mem_free (err);
          retcode = 1;
      }
      else {
@@@ -1431,7 -1431,7 +1432,7 @@@
  	form = use_display_format (p, mini_status_format (p), &err, 1);
  
  	if (err){
- 	    g_free (err);
+ 	    mhl_mem_free (err);
  	    retcode += 2;
  	}
  	else {
@@@ -1448,12 -1448,12 +1449,12 @@@
      if (retcode)
        message( 1, _("Warning" ), _( "User supplied format looks invalid, reverting to default." ) );
      if (retcode & 0x01){
-       g_free (p->user_format);
+       mhl_mem_free (p->user_format);
 -      p->user_format = g_strdup (DEFAULT_USER_FORMAT);
 +      p->user_format = mhl_str_dup (DEFAULT_USER_FORMAT);
      }
      if (retcode & 0x02){
-       g_free (p->user_status_format [p->list_type]);
+       mhl_mem_free (p->user_status_format [p->list_type]);
 -      p->user_status_format [p->list_type] = g_strdup (DEFAULT_USER_FORMAT);
 +      p->user_status_format [p->list_type] = mhl_str_dup (DEFAULT_USER_FORMAT);
      }
  
      return retcode;
@@@ -1975,12 -1975,12 +1976,12 @@@ do_enter_on_file_entry (file_entry *fe
  	return 1;
  
      /* Check if the file is executable */
 -    full_name = concat_dir_and_file (current_panel->cwd, fe->fname);
 +    full_name = mhl_str_dir_plus_file (current_panel->cwd, fe->fname);
      if (!is_exe (fe->st.st_mode) || !if_link_is_exe (full_name, fe)) {
- 	g_free (full_name);
+ 	mhl_mem_free (full_name);
  	return 0;
      }
-     g_free (full_name);
+     mhl_mem_free (full_name);
  
      if (confirm_execute) {
  	if (query_dialog
@@@ -1994,9 -1994,9 +1995,9 @@@
  	char *tmp;
  	int ret;
  
 -	tmp = concat_dir_and_file (vfs_get_current_dir (), fe->fname);
 +	tmp = mhl_str_dir_plus_file (vfs_get_current_dir (), fe->fname);
  	ret = mc_setctl (tmp, VFS_SETCTL_RUN, NULL);
- 	g_free (tmp);
+ 	mhl_mem_free (tmp);
  	/* We took action only if the dialog was shown or the execution
  	 * was successful */
  	return confirm_execute || (ret == 0);
@@@ -2006,9 -2006,9 +2007,9 @@@
      {
  	char *tmp = name_quote (fe->fname, 0);
  	char *cmd = g_strconcat (".", PATH_SEP_STR, tmp, (char *) NULL);
- 	g_free (tmp);
+ 	mhl_mem_free (tmp);
  	shell_execute (cmd, 0);
- 	g_free (cmd);
+ 	mhl_mem_free (cmd);
      }
  
      return 1;
@@@ -2031,10 -2031,10 +2032,10 @@@ chdir_other_panel (WPanel *panel
      }
  
      if (!S_ISDIR (panel->dir.list [panel->selected].st.st_mode)) {
 -        new_dir = concat_dir_and_file (panel->cwd, "..");
 +        new_dir = mhl_str_dir_plus_file (panel->cwd, "..");
  	sel_entry = strrchr(panel->cwd, PATH_SEP);
      } else
 -        new_dir = concat_dir_and_file (panel->cwd, panel->dir.list [panel->selected].fname);
 +        new_dir = mhl_str_dir_plus_file (panel->cwd, panel->dir.list [panel->selected].fname);
  
      change_panel ();
      do_cd (new_dir, cd_exact);
@@@ -2044,7 -2044,7 +2045,7 @@@
   
      move_down (panel);
  
-     g_free (new_dir);
+     mhl_mem_free (new_dir);
  }
  
  /*
@@@ -2098,9 -2098,9 +2099,9 @@@ chdir_to_readlink (WPanel *panel
  	    p[1] = 0;
  	}
  	if (*buffer == PATH_SEP)
 -	    new_dir = g_strdup (buffer);
 +	    new_dir = mhl_str_dup (buffer);
  	else
 -	    new_dir = concat_dir_and_file (panel->cwd, buffer);
 +	    new_dir = mhl_str_dir_plus_file (panel->cwd, buffer);
  
  	change_panel ();
  	do_cd (new_dir, cd_exact);
@@@ -2108,7 -2108,7 +2109,7 @@@
  
  	move_down (panel);
  
- 	g_free (new_dir);
+ 	mhl_mem_free (new_dir);
      }
  }
  
@@@ -2252,10 -2252,10 +2253,10 @@@ panel_callback (Widget *w, widget_msg_
  	current_panel = panel;
  	panel->active = 1;
  	if (mc_chdir (panel->cwd) != 0) {
 -	    char *cwd = strip_password (g_strdup (panel->cwd), 1);
 +	    char *cwd = strip_password (mhl_str_dup (panel->cwd), 1);
  	    message (D_ERROR, MSG_ERROR, _(" Cannot chdir to \"%s\" \n %s "),
  		     cwd, unix_error_string (errno));
- 	    g_free(cwd);
+ 	    mhl_mem_free(cwd);
  	} else
  	    subshell_chdir (panel->cwd);
  
@@@ -2464,7 -2464,7 +2465,7 @@@ panel_re_sort (WPanel *panel
      if (panel == NULL)
  	    return;
  
 -    filename = g_strdup (selection (panel)->fname);
 +    filename = mhl_str_dup (selection (panel)->fname);
      unselect_item (panel);
      do_sort (&panel->dir, panel->sort_type, panel->count-1, panel->reverse,
               panel->case_sensitive, panel->exec_first);
@@@ -2475,7 -2475,7 +2476,7 @@@
  	    break;
  	}
      }
-     g_free (filename);
+     mhl_mem_free (filename);
      panel->top_file = panel->selected - ITEMS (panel)/2;
      if (panel->top_file < 0)
  	panel->top_file = 0;
@@@ -2495,10 -2495,10 +2496,10 @@@ panel_set_sort_order (WPanel *panel, so
      if (sort_order == (sortfn *) unsorted){
  	char *current_file;
  
 -	current_file = g_strdup (panel->dir.list [panel->selected].fname);
 +	current_file = mhl_str_dup (panel->dir.list [panel->selected].fname);
  	panel_reload (panel);
  	try_to_select (panel, current_file);
- 	g_free (current_file);
+ 	mhl_mem_free (current_file);
      }
      panel_re_sort (panel);
  }
diff --combined src/setup.c
index 02df102,9fcf767..eaa86a7
--- a/src/setup.c
+++ b/src/setup.c
@@@ -23,7 -23,7 +23,8 @@@
  #include <sys/types.h>
  #include <sys/stat.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -245,11 -245,11 +246,11 @@@ panel_save_setup (struct WPanel *panel
      char buffer [BUF_TINY];
      int  i;
  
 -    g_snprintf (buffer, sizeof (buffer), "%d", panel->reverse);
 +    snprintf (buffer, sizeof (buffer), "%d", panel->reverse);
      save_string (section, "reverse", buffer, profile_name);
 -    g_snprintf (buffer, sizeof (buffer), "%d", panel->case_sensitive);
 +    snprintf (buffer, sizeof (buffer), "%d", panel->case_sensitive);
      save_string (section, "case_sensitive", buffer, profile_name);
 -    g_snprintf (buffer, sizeof (buffer), "%d", panel->exec_first);
 +    snprintf (buffer, sizeof (buffer), "%d", panel->exec_first);
      save_string (section, "exec_first", buffer, profile_name);
      for (i = 0; sort_names [i].key; i++)
  	if (sort_names [i].sort_type == (sortfn *) panel->sort_type){
@@@ -268,12 -268,12 +269,12 @@@
  			       panel->user_format, profile_name);
  
      for (i = 0; i < LIST_TYPES; i++){
 -	g_snprintf (buffer, sizeof (buffer), "user_status%d", i);
 +	snprintf (buffer, sizeof (buffer), "user_status%d", i);
  	save_string (section, buffer,
  	    panel->user_status_format [i], profile_name);
      }
  
 -    g_snprintf (buffer, sizeof (buffer), "%d", panel->user_mini_status);
 +    snprintf (buffer, sizeof (buffer), "%d", panel->user_mini_status);
      save_string (section, "user_mini_status", buffer,
  			       profile_name);
  }
@@@ -285,15 -285,15 +286,15 @@@ save_layout (void
      int  i;
      char buffer [BUF_TINY];
  
 -    profile = concat_dir_and_file (home_dir, PROFILE_NAME);
 +    profile = mhl_str_dir_plus_file (home_dir, PROFILE_NAME);
  
      /* Save integer options */
      for (i = 0; layout [i].opt_name; i++){
 -	g_snprintf (buffer, sizeof (buffer), "%d", *layout [i].opt_addr);
 +	snprintf (buffer, sizeof (buffer), "%d", *layout [i].opt_addr);
  	save_string ("Layout", layout [i].opt_name, buffer, profile);
      }
  
-     g_free (profile);
+     mhl_mem_free (profile);
  }
  
  void
@@@ -302,7 -302,7 +303,7 @@@ save_configure (void
      char *profile;
      int  i;
  
 -    profile = concat_dir_and_file (home_dir, PROFILE_NAME);
 +    profile = mhl_str_dir_plus_file (home_dir, PROFILE_NAME);
  
      /* Save integer options */
      for (i = 0; int_options[i].opt_name; i++)
@@@ -313,7 -313,7 +314,7 @@@
  	set_config_string (profile, str_options[i].opt_name,
  	    *str_options[i].opt_addr);
  
-     g_free (profile);
+     mhl_mem_free (profile);
  }
  
  static void
@@@ -350,7 -350,7 +351,7 @@@ save_setup (void
      char *profile;
  
      saving_setup = 1;
 -    profile = concat_dir_and_file (home_dir, PROFILE_NAME);
 +    profile = mhl_str_dir_plus_file (home_dir, PROFILE_NAME);
  
      save_configure ();
  
@@@ -380,7 -380,7 +381,7 @@@
      		 get_codepage_id( display_codepage ), profile_name );
  #endif /* HAVE_CHARSET */
  
-     g_free (profile);
+     mhl_mem_free (profile);
      saving_setup = 0;
  }
  
@@@ -413,15 -413,15 +414,15 @@@ panel_load_setup (WPanel *panel, const 
  	}
  
      /* User formats */
-     g_free (panel->user_format);
+     mhl_mem_free (panel->user_format);
 -    panel->user_format = g_strdup (get_profile_string (section, "user_format",
 +    panel->user_format = mhl_str_dup (get_profile_string (section, "user_format",
  						     DEFAULT_USER_FORMAT,
  						     profile_name));
      for (i = 0; i < LIST_TYPES; i++){
- 	g_free (panel->user_status_format [i]);
+ 	mhl_mem_free (panel->user_status_format [i]);
 -	g_snprintf (buffer, sizeof (buffer), "user_status%d", i);
 +	snprintf (buffer, sizeof (buffer), "user_status%d", i);
  	panel->user_status_format [i] =
 -	    g_strdup (get_profile_string (section, buffer,
 +	    mhl_str_dup (get_profile_string (section, buffer,
  			DEFAULT_USER_FORMAT, profile_name));
      }
  
@@@ -470,8 -470,8 +471,8 @@@ do_load_string (const char *s, const ch
  
      load_string (s, ss, def, buffer, BUF_SMALL);
  
 -    p = g_strdup (buffer);
 +    p = mhl_str_dup (buffer);
-     g_free (buffer);
+     mhl_mem_free (buffer);
      return p;
  }
  #endif /* !USE_NETCODE */
@@@ -485,14 -485,14 +486,14 @@@ setup_init (void
      if (profile_name)
  	    return profile_name;
  
 -    profile = concat_dir_and_file (home_dir, PROFILE_NAME);
 +    profile = mhl_str_dir_plus_file (home_dir, PROFILE_NAME);
      if (!exist_file (profile)){
 -	inifile = concat_dir_and_file (mc_home, "mc.ini");
 +	inifile = mhl_str_dir_plus_file (mc_home, "mc.ini");
  	if (exist_file (inifile)){
- 	    g_free (profile);
+ 	    mhl_mem_free (profile);
  	    profile = inifile;
  	} else
- 	    g_free (inifile);
+ 	    mhl_mem_free (inifile);
      }
  
      profile_name = profile;
@@@ -510,7 -510,7 +511,7 @@@ load_setup (void
  
      /* mc.lib is common for all users, but has priority lower than
         ~/.mc/ini.  FIXME: it's only used for keys and treestore now */
 -    global_profile_name = concat_dir_and_file (mc_home, "mc.lib");
 +    global_profile_name = mhl_str_dir_plus_file (mc_home, "mc.lib");
  
      /* Load integer boolean options */
      for (i = 0; int_options[i].opt_name; i++)
@@@ -542,7 -542,7 +543,7 @@@
  	if (vfs_file_is_local (buffer))
  	    other_dir = buffer;
  	else
- 	    g_free (buffer);
+ 	    mhl_mem_free (buffer);
      }
  
      boot_current_is_left =
@@@ -595,7 -595,7 +596,7 @@@ load_anon_passwd (
  
      load_string ("Misc", "ftpfs_password", "", buffer, sizeof (buffer));
      if (buffer [0])
 -	return g_strdup (buffer);
 +	return mhl_str_dup (buffer);
      else
  	return 0;
  }
@@@ -603,8 -603,8 +604,8 @@@
  
  void done_setup (void)
  {
-     g_free (profile_name);
-     g_free (global_profile_name);
+     mhl_mem_free (profile_name);
+     mhl_mem_free (global_profile_name);
      done_hotlist ();
      done_panelize ();
  /*    directory_history_free (); */
@@@ -623,7 -623,7 +624,7 @@@ load_keys_from_section (const char *ter
  
      section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
      profile_keys = profile_init_iterator (section_name, profile_name);
-     g_free (section_name);
+     mhl_mem_free (section_name);
      while (profile_keys){
  	profile_keys = profile_iterator_next (profile_keys, &key, &value);
  
@@@ -637,7 -637,7 +638,7 @@@
  	if (key_code){
  	    valcopy = convert_controls (value);
  	    define_sequence (key_code, valcopy, MCKEY_NOACTION);
- 	    g_free (valcopy);
+ 	    mhl_mem_free (valcopy);
  	}
      }
  }
diff --combined src/subshell.c
index 8fcc7e4,5386352..2f2f9bf
--- a/src/subshell.c
+++ b/src/subshell.c
@@@ -44,7 -44,7 +44,8 @@@
  #  include <stropts.h> /* For I_PUSH */
  #endif /* HAVE_STROPTS_H */
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"	/* LINES */
@@@ -229,9 -229,9 +230,9 @@@ init_subshell_child (const char *pty_na
      mc_sid = getsid (0);
      if (mc_sid != -1) {
  	char sid_str[BUF_SMALL];
 -	g_snprintf (sid_str, sizeof (sid_str), "MC_SID=%ld",
 +	snprintf (sid_str, sizeof (sid_str), "MC_SID=%ld",
  		    (long) mc_sid);
 -	putenv (g_strdup (sid_str));
 +	putenv (mhl_str_dup (sid_str));
      }
  #endif				/* HAVE_GETSID */
  
@@@ -422,7 -422,7 +423,7 @@@ init_subshell (void
  	/* Create a pipe for receiving the subshell's CWD */
  
  	if (subshell_type == TCSH) {
 -	    g_snprintf (tcsh_fifo, sizeof (tcsh_fifo), "%s/mc.pipe.%d",
 +	    snprintf (tcsh_fifo, sizeof (tcsh_fifo), "%s/mc.pipe.%d",
  			mc_tmpdir (), (int) getpid ());
  	    if (mkfifo (tcsh_fifo, 0600) == -1) {
  		fprintf (stderr, "mkfifo(%s) failed: %s\r\n", tcsh_fifo,
@@@ -470,19 -470,19 +471,19 @@@
  
      switch (subshell_type) {
      case BASH:
 -	g_snprintf (precmd, sizeof (precmd),
 +	snprintf (precmd, sizeof (precmd),
  		    " PROMPT_COMMAND='pwd>&%d;kill -STOP $$'\n",
  		    subshell_pipe[WRITE]);
  	break;
  
      case ZSH:
 -	g_snprintf (precmd, sizeof (precmd),
 +	snprintf (precmd, sizeof (precmd),
  		    " precmd(){ pwd>&%d;kill -STOP $$ }\n",
  		    subshell_pipe[WRITE]);
  	break;
  
      case TCSH:
 -	g_snprintf (precmd, sizeof (precmd),
 +	snprintf (precmd, sizeof (precmd),
  		    "set echo_style=both;"
  		    "alias precmd 'echo $cwd:q >>%s;kill -STOP $$'\n",
  		    tcsh_fifo);
@@@ -672,8 -672,8 +673,8 @@@ exit_subshell (void
  			 tcsh_fifo, unix_error_string (errno));
  	}
  
- 	g_free (subshell_prompt);
- 	g_free (pty_buffer);
+ 	mhl_mem_free (subshell_prompt);
+ 	mhl_mem_free (pty_buffer);
  	subshell_prompt = NULL;
  	pty_buffer = NULL;
      }
@@@ -764,7 -764,7 +765,7 @@@ do_subshell_chdir (const char *director
  	char *temp = subshell_name_quote (directory);
  	if (temp) {
  	    write_all (subshell_pty, temp, strlen (temp));
- 	    g_free (temp);
+ 	    mhl_mem_free (temp);
  	} else {
  	    /* Should not happen unless the directory name is so long
  	       that we don't have memory to quote it.  */
@@@ -798,9 -798,9 +799,9 @@@
  	}
  
  	if (bPathNotEq && strcmp (current_panel->cwd, ".")) {
 -	    char *cwd = strip_password (g_strdup (current_panel->cwd), 1);
 +	    char *cwd = strip_password (mhl_str_dup (current_panel->cwd), 1);
  	    fprintf (stderr, _("Warning: Cannot change to %s.\n"), cwd);
- 	    g_free (cwd);
+ 	    mhl_mem_free (cwd);
  	}
      }
  
diff --combined src/tree.c
index 580cfc4,532d693..8ff94ef
--- a/src/tree.c
+++ b/src/tree.c
@@@ -33,6 -33,8 +33,8 @@@
  #include <stdio.h>
  #include <string.h>
  
+ #include <mhl/memory.h>
+ 
  #include "global.h"
  #include "tty.h"
  #include "color.h"
@@@ -126,7 -128,7 +128,7 @@@ static void tree_destroy (WTree *tree
      tree_store_remove_entry_remove_hook (remove_callback);
      save_tree (tree);
  
-     g_free (tree->tree_shown);
+     mhl_mem_free (tree->tree_shown);
      tree->tree_shown = 0;
      tree->selected_ptr = NULL;
  }
@@@ -206,7 -208,7 +208,7 @@@ static void show_tree (WTree *tree
  	x = y = 1;
      }
  
-     g_free (tree->tree_shown);
+     mhl_mem_free (tree->tree_shown);
      tree->tree_shown = g_new (tree_entry*, tree_lines);
  
      for (i = 0; i < tree_lines; i++)
@@@ -597,7 -599,7 +599,7 @@@ static void tree_copy (WTree *tree, con
  
      if (!tree->selected_ptr)
  	return;
 -    g_snprintf (cmd_buf, sizeof(cmd_buf), _("Copy \"%s\" directory to:"),
 +    snprintf (cmd_buf, sizeof(cmd_buf), _("Copy \"%s\" directory to:"),
  	     name_trunc (tree->selected_ptr->name, 50));
      dest = input_expand_dialog (_(" Copy "), cmd_buf, MC_HISTORY_FM_TREE_COPY, default_dest);
  
@@@ -605,7 -607,7 +607,7 @@@
  	return;
  
      if (!*dest){
- 	g_free (dest);
+ 	mhl_mem_free (dest);
  	return;
      }
  
@@@ -614,7 -616,7 +616,7 @@@
      copy_dir_dir (ctx, tree->selected_ptr->name, dest, 1, 0, 0, 0, &count, &bytes);
      file_op_context_destroy (ctx);
  
-     g_free (dest);
+     mhl_mem_free (dest);
  }
  
  static void
@@@ -640,25 -642,25 +642,25 @@@ static void tree_move (WTree *tree, con
  
      if (!tree->selected_ptr)
  	return;
 -    g_snprintf (cmd_buf, sizeof (cmd_buf), _("Move \"%s\" directory to:"),
 +    snprintf (cmd_buf, sizeof (cmd_buf), _("Move \"%s\" directory to:"),
  	     name_trunc (tree->selected_ptr->name, 50));
      dest = input_expand_dialog (_(" Move "), cmd_buf, MC_HISTORY_FM_TREE_MOVE, default_dest);
      if (!dest)
  	return;
      if (!*dest){
- 	g_free (dest);
+ 	mhl_mem_free (dest);
  	return;
      }
      if (stat (dest, &buf)){
  	message (D_ERROR, MSG_ERROR, _(" Cannot stat the destination \n %s "),
  		 unix_error_string (errno));
- 	g_free (dest);
+ 	mhl_mem_free (dest);
  	return;
      }
      if (!S_ISDIR (buf.st_mode)){
  	file_error (_(" Destination \"%s\" must be a directory \n %s "),
  		    dest);
- 	g_free (dest);
+ 	mhl_mem_free (dest);
  	return;
      }
  
@@@ -667,7 -669,7 +669,7 @@@
      move_dir_dir (ctx, tree->selected_ptr->name, dest, &count, &bytes);
      file_op_context_destroy (ctx);
  
-     g_free (dest);
+     mhl_mem_free (dest);
  }
  
  static void
@@@ -716,7 -718,7 +718,7 @@@ tree_rmdir_cmd (WTree *tree
  			     tree->selected_ptr->name);
  	result =
  	    query_dialog (_(" Delete "), buf, D_ERROR, 2, _("&Yes"), _("&No"));
- 	g_free (buf);
+ 	mhl_mem_free (buf);
  	if (result != 0)
  	    return;
      }
diff --combined src/treestore.c
index a9f2e81,dc41184..cb08cb2
--- a/src/treestore.c
+++ b/src/treestore.c
@@@ -41,8 -41,7 +41,9 @@@
  #include <sys/stat.h>
  #include <unistd.h>
  
 +#include <mhl/types.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "treestore.h"
@@@ -136,7 -135,7 +137,7 @@@ tree_store_get(void
  static char *
  decode(char *buffer)
  {
 -    char *res = g_strdup(buffer);
 +    char *res = mhl_str_dup(buffer);
      char *p, *q;
  
      for (p = q = res; *p; p++, q++) {
@@@ -238,7 -237,7 +239,7 @@@ tree_store_load_from(char *name
  		}
  		strcpy(oldname, name);
  	    }
- 	    g_free(name);
+ 	    mhl_mem_free(name);
  	}
  	fclose(file);
      }
@@@ -267,9 -266,9 +268,9 @@@ tree_store_load(void
      char *name;
      int retval;
  
 -    name = concat_dir_and_file(home_dir, MC_TREE);
 +    name = mhl_str_dir_plus_file(home_dir, MC_TREE);
      retval = tree_store_load_from(name);
-     g_free(name);
+     mhl_mem_free(name);
  
      return retval;
  }
@@@ -336,12 -335,12 +337,12 @@@ tree_store_save_to(char *name
  
  		i = fprintf(file, "%d:%d %s\n", current->scanned, common,
  			    encoded);
- 		g_free(encoded);
+ 		mhl_mem_free(encoded);
  	    } else {
  		char *encoded = encode(current->name);
  
  		i = fprintf(file, "%d:%s\n", current->scanned, encoded);
- 		g_free(encoded);
+ 		mhl_mem_free(encoded);
  	    }
  
  	    if (i == EOF) {
@@@ -373,19 -372,19 +374,19 @@@ tree_store_save(void
      char *name;
      int retval;
  
 -    tmp = concat_dir_and_file(home_dir, MC_TREE_TMP);
 +    tmp = mhl_str_dir_plus_file(home_dir, MC_TREE_TMP);
      retval = tree_store_save_to(tmp);
  
      if (retval) {
- 	g_free(tmp);
+ 	mhl_mem_free(tmp);
  	return retval;
      }
  
 -    name = concat_dir_and_file(home_dir, MC_TREE);
 +    name = mhl_str_dir_plus_file(home_dir, MC_TREE);
      retval = rename(tmp, name);
  
-     g_free(tmp);
-     g_free(name);
+     mhl_mem_free(tmp);
+     mhl_mem_free(name);
  
      if (retval)
  	return errno;
@@@ -445,7 -444,7 +446,7 @@@ tree_store_add_entry(const char *name
      }
  
      /* Calculate attributes */
 -    new->name = g_strdup(name);
 +    new->name = mhl_str_dup(name);
      len = strlen(new->name);
      new->sublevel = 0;
      for (i = 0; i < len; i++)
@@@ -473,7 -472,7 +474,7 @@@
  
      if (new->sublevel > 1) {
  	/* Let's check if the parent directory is in the tree */
 -	char *parent = g_strdup(new->name);
 +	char *parent = mhl_str_dup(new->name);
  	int i;
  
  	for (i = strlen(parent) - 1; i > 1; i--) {
@@@ -483,7 -482,7 +484,7 @@@
  		break;
  	    }
  	}
- 	g_free(parent);
+ 	mhl_mem_free(parent);
      }
  
      tree_store_dirty(TRUE);
@@@ -548,8 -547,8 +549,8 @@@ remove_entry(tree_entry * entry
  	ts.tree_last = entry->prev;
  
      /* Free the memory used by the entry */
-     g_free(entry->name);
-     g_free(entry);
+     mhl_mem_free(entry->name);
+     mhl_mem_free(entry);
  
      return ret;
  }
@@@ -607,7 -606,7 +608,7 @@@ tree_store_mark_checked(const char *sub
      if (ts.check_name[0] == PATH_SEP && ts.check_name[1] == 0)
  	name = g_strconcat(PATH_SEP_STR, subname, (char *) NULL);
      else
 -	name = concat_dir_and_file(ts.check_name, subname);
 +	name = mhl_str_dir_plus_file(ts.check_name, subname);
  
      /* Search for the subdirectory */
      current = ts.check_start;
@@@ -617,9 -616,9 +618,9 @@@
      if (flag != 0) {
  	/* Doesn't exist -> add it */
  	current = tree_store_add_entry(name);
 -	ts.add_queue = g_list_prepend(ts.add_queue, g_strdup(name));
 +	ts.add_queue = g_list_prepend(ts.add_queue, mhl_str_dup(name));
      }
-     g_free(name);
+     mhl_mem_free(name);
  
      /* Clear the deletion mark from the subdirectory and its children */
      base = current;
@@@ -662,12 -661,12 +663,12 @@@ tree_store_start_check(const char *path
  	    return NULL;
  
  	current = tree_store_add_entry(path);
 -	ts.check_name = g_strdup(path);
 +	ts.check_name = mhl_str_dup(path);
  
  	return current;
      }
  
 -    ts.check_name = g_strdup(path);
 +    ts.check_name = mhl_str_dup(path);
  
      retval = current;
  
@@@ -718,11 -717,11 +719,11 @@@ tree_store_end_check(void
      ts.add_queue = g_list_reverse(ts.add_queue);
      the_queue = ts.add_queue;
      ts.add_queue = NULL;
-     g_free(ts.check_name);
+     mhl_mem_free(ts.check_name);
      ts.check_name = NULL;
  
      for (l = the_queue; l; l = l->next) {
- 	g_free(l->data);
+ 	mhl_mem_free(l->data);
      }
  
      g_list_free(the_queue);
@@@ -739,13 -738,13 +740,13 @@@ process_special_dirs(GList ** special_d
  			    "", buffer, 4096, file);
      s = buffer;
      while ((token = strtok(s, ",")) != NULL) {
 -	*special_dirs = g_list_prepend(*special_dirs, g_strdup(token));
 +	*special_dirs = g_list_prepend(*special_dirs, mhl_str_dup(token));
  	s = NULL;
      }
-     g_free(buffer);
+     mhl_mem_free(buffer);
  }
  
 -static gboolean
 +static bool
  should_skip_directory(const char *dir)
  {
      static GList *special_dirs;
@@@ -797,12 -796,12 +798,12 @@@ tree_store_rescan(const char *dir
  		    continue;
  	    }
  
 -	    full_name = concat_dir_and_file(dir, dp->d_name);
 +	    full_name = mhl_str_dir_plus_file(dir, dp->d_name);
  	    if (mc_lstat(full_name, &buf) != -1) {
  		if (S_ISDIR(buf.st_mode))
  		    tree_store_mark_checked(dp->d_name);
  	    }
- 	    g_free(full_name);
+ 	    mhl_mem_free(full_name);
  	}
  	mc_closedir(dirp);
      }
diff --combined src/user.c
index 84d59ab,3b7378c..8f670ea
--- a/src/user.c
+++ b/src/user.c
@@@ -23,7 -23,7 +23,8 @@@
  #include <stdio.h>
  #include <string.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -144,9 -144,9 +145,9 @@@ int check_format_var (const char *p, ch
  	var_name = g_strndup (p + 4, dots-2 - (p+3));
  
  	value = getenv (var_name);
- 	g_free (var_name);
+ 	mhl_mem_free (var_name);
  	if (value){
 -	    *v = g_strdup (value);
 +	    *v = mhl_str_dup (value);
  	    return q-p;
  	}	
  	var_name = g_strndup (dots, q - dots);
@@@ -181,7 -181,7 +182,7 @@@ expand_format (struct WEdit *edit_widge
      char c_lc;
  
      if (c == '%')
 -	return g_strdup ("%");
 +	return mhl_str_dup ("%");
  
      if (edit_one_file != NULL)
  	fname = edit_widget->filename;
@@@ -190,7 -190,7 +191,7 @@@
  	    panel = current_panel;
  	else {
  	    if (get_other_type () != view_listing)
 -		return g_strdup ("");
 +		return mhl_str_dup ("");
  	    panel = other_panel;
  	}
  	fname = panel->dir.list[panel->selected].fname;
@@@ -223,7 -223,7 +224,7 @@@
  
  	    qstr = (*quote_func) (cwd, 0);
  
- 	    g_free (cwd);
+ 	    mhl_mem_free (cwd);
  
  	    return qstr;
  	}
@@@ -233,14 -233,14 +234,14 @@@
  	break;
      case 'y':			/* syntax type */
  	if (edit_widget && edit_widget->syntax_type)
 -	    return g_strdup (edit_widget->syntax_type);
 +	    return mhl_str_dup (edit_widget->syntax_type);
  	break;
      case 'k':			/* block file name */
      case 'b':			/* block file name / strip extension */  {
  	    if (edit_widget) {
  		char *file = g_strconcat (home_dir, PATH_SEP_STR BLOCK_FILE, (char *) NULL);
  		fname = (*quote_func) (file, 0);
- 		g_free (file);
+ 		mhl_mem_free (file);
  		return fname;
  	    } else if (c_lc == 'b') {
  		return strip_ext ((*quote_func) (fname, 0));
@@@ -268,7 -268,7 +269,7 @@@
  	    char *block, *tmp;
  
  	    if (!panel)
 -		return g_strdup ("");
 +		return mhl_str_dup ("");
  
  	    for (i = 0; i < panel->count; i++)
  		if (panel->dir.list[i].f.marked)
@@@ -280,7 -280,7 +281,7 @@@
  		if (panel->dir.list[i].f.marked) {
  		    strcat (block, tmp =
  			    (*quote_func) (panel->dir.list[i].fname, 0));
- 		    g_free (tmp);
+ 		    mhl_mem_free (tmp);
  		    strcat (block, " ");
  		    if (c_lc == 'u')
  			do_file_mark (panel, i, 0);
@@@ -288,7 -288,7 +289,7 @@@
  	    return block;
  	}			/* sub case block */
      }				/* switch */
 -    result = g_strdup ("% ");
 +    result = mhl_str_dup ("% ");
      result[1] = c;
      return result;
  }
@@@ -470,7 -470,7 +471,7 @@@ debug_out (char *start, char *end, int 
  
  	}
  	debug_flag = 0;
- 	g_free (msg);
+ 	mhl_mem_free (msg);
  	msg = NULL;
      } else {
  	const char *type;
@@@ -494,7 -494,7 +495,7 @@@
  	else
  	    p = g_strdup_printf ("%s%s%.*s \n", msg ? msg : "", type,
  			(int) (end - start), start);
- 	g_free (msg);
+ 	mhl_mem_free (msg);
  	msg = p;
      }
  }
@@@ -612,15 -612,15 +613,15 @@@ execute_menu_command (WEdit *edit_widge
  		    /* User canceled */
  		    fclose (cmd_file);
  		    unlink (file_name);
-                     g_free (file_name);
+                     mhl_mem_free (file_name);
  		    return;
  		}
  		if (do_quote) {
      		    fputs (tmp = name_quote (parameter, 0), cmd_file);
- 		    g_free (tmp);
+ 		    mhl_mem_free (tmp);
  		} else
  		    fputs (parameter, cmd_file);
- 		g_free (parameter);
+ 		mhl_mem_free (parameter);
  		parameter = 0;
  	    } else {
  		if (parameter < &prompt [sizeof (prompt) - 1]) {
@@@ -639,7 -639,7 +640,7 @@@
  	    else{
  		char *text = expand_format (edit_widget, *commands, do_quote);
  		fputs (text, cmd_file);
- 		g_free (text);
+ 		mhl_mem_free (text);
  	    }
  	} else {
  	    if (*commands == '%') {
@@@ -665,10 -665,10 +666,10 @@@
  	 * on no-exec filesystems. */
  	char *cmd = g_strconcat("/bin/sh ", file_name, (char *)NULL);
  	shell_execute (cmd, EXECUTE_HIDE);
- 	g_free(cmd);
+ 	mhl_mem_free(cmd);
      }
      unlink (file_name);
-     g_free (file_name);
+     mhl_mem_free (file_name);
  }
  
  /* 
@@@ -720,14 -720,14 +721,14 @@@ user_menu_cmd (struct WEdit *edit_widge
  	return;
      }
      
 -    menu = g_strdup (edit_widget ? CEDIT_LOCAL_MENU : MC_LOCAL_MENU);
 +    menu = mhl_str_dup (edit_widget ? CEDIT_LOCAL_MENU : MC_LOCAL_MENU);
      if (!exist_file (menu) || !menu_file_own (menu)){
- 	g_free (menu);
+ 	mhl_mem_free (menu);
 -        menu = concat_dir_and_file \
 +        menu = mhl_str_dir_plus_file \
                              (home_dir, edit_widget ? CEDIT_HOME_MENU : MC_HOME_MENU);
  	if (!exist_file (menu)){
- 	    g_free (menu);
+ 	    mhl_mem_free (menu);
 -	    menu = concat_dir_and_file \
 +	    menu = mhl_str_dir_plus_file \
                          (mc_home, edit_widget ? CEDIT_GLOBAL_MENU : MC_GLOBAL_MENU);
  	}
      }
@@@ -735,7 -735,7 +736,7 @@@
      if ((data = load_file (menu)) == NULL){
  	message (D_ERROR, MSG_ERROR, _(" Cannot open file %s \n %s "),
  		 menu, unix_error_string (errno));
- 	g_free (menu);
+ 	mhl_mem_free (menu);
  	menu = NULL;
  	return;
      }
@@@ -840,9 -840,9 +841,9 @@@
      }
  
      easy_patterns = old_patterns;
-     g_free (menu);
+     mhl_mem_free (menu);
      menu = NULL;
-     g_free (entries);
-     g_free (data);
+     mhl_mem_free (entries);
+     mhl_mem_free (data);
  }
  
diff --combined src/util.c
index 9e20751,46dcf96..dc03468
--- a/src/util.c
+++ b/src/util.c
@@@ -34,8 -34,7 +34,9 @@@
  #include <sys/stat.h>
  #include <unistd.h>
  
 +#include <mhl/escape.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "profile.h"
@@@ -220,7 -219,7 +221,7 @@@ char 
  fake_name_quote (const char *s, int quote_percent)
  {
      (void) quote_percent;
 -    return g_strdup (s);
 +    return mhl_str_dup (s);
  }
  
  /*
@@@ -229,27 -228,22 +230,27 @@@
   * Return static buffer, no need to free() it.
   */
  const char *
 -name_trunc (const char *txt, int trunc_len)
 +name_trunc (const char *txt, size_t trunc_len)
  {
      static char x[MC_MAXPATHLEN + MC_MAXPATHLEN];
 -    int txt_len;
 +    size_t txt_len;
      char *p;
  
 -    if ((size_t) trunc_len > sizeof (x) - 1) {
 +    if (!txt)
 +	return NULL;
 +    if (!*txt)
 +	return txt;
 +
 +    if (trunc_len > sizeof (x) - 1) {
  	trunc_len = sizeof (x) - 1;
      }
      txt_len = strlen (txt);
      if (txt_len <= trunc_len) {
  	strcpy (x, txt);
      } else {
 -	int y = (trunc_len / 2) + (trunc_len % 2);
 -	strncpy (x, txt, y);
 -	strncpy (x + y, txt + txt_len - (trunc_len / 2), trunc_len / 2);
 +	size_t y = (trunc_len / 2) + (trunc_len % 2);
 +	strncpy (x, txt, (size_t) y);
 +	strncpy (x + y, txt + (txt_len - (trunc_len / 2)), trunc_len / 2);
  	x[y] = '~';
      }
      x[trunc_len] = 0;
@@@ -265,12 -259,12 +266,12 @@@
   * reasons.
   */
  const char *
 -path_trunc (const char *path, int trunc_len) {
 +path_trunc (const char *path, size_t trunc_len) {
      const char *ret;
 -    char *secure_path = strip_password (g_strdup (path), 1);
 +    char *secure_path = strip_password (mhl_str_dup (path), 1);
      
      ret = name_trunc (secure_path, trunc_len);
-     g_free (secure_path);
+     mhl_mem_free (secure_path);
      
      return ret;
  }
@@@ -290,7 -284,7 +291,7 @@@ size_trunc (double size
  	    xtra = "M";
  	}
      }
 -    g_snprintf (x, sizeof (x), "%.0f%s", (size/divisor), xtra);
 +    snprintf (x, sizeof (x), "%.0f%s", (size/divisor), xtra);
      return x;
  }
  
@@@ -349,18 -343,18 +350,18 @@@ size_trunc_len (char *buffer, int len, 
  	if (size == 0) {
  	    if (j == units) {
  		/* Empty files will print "0" even with minimal width.  */
 -		g_snprintf (buffer, len + 1, "0");
 +		snprintf (buffer, len + 1, "0");
  		break;
  	    }
  
  	    /* Use "~K" or just "K" if len is 1.  Use "B" for bytes.  */
 -	    g_snprintf (buffer, len + 1, (len > 1) ? "~%s" : "%s",
 +	    snprintf (buffer, len + 1, (len > 1) ? "~%s" : "%s",
  			(j > 1) ? suffix[j - 1] : "B");
  	    break;
  	}
  
  	if (size < power10 [len - (j > 0)]) {
 -	    g_snprintf (buffer, len + 1, "%lu%s", (unsigned long) size, suffix[j]);
 +	    snprintf (buffer, len + 1, "%lu%s", (unsigned long) size, suffix[j]);
  	    break;
  	}
  
@@@ -586,7 -580,7 +587,7 @@@ convert_pattern (const char *pattern, i
  	*d = 0;
  	return new_pattern;
      } else
 -	return  g_strdup (pattern);
 +	return  mhl_str_dup (pattern);
  }
  
  int
@@@ -601,12 -595,12 +602,12 @@@ regexp_match (const char *pattern, cons
      if (!old_pattern || STRCOMP (old_pattern, pattern) || old_type != match_type){
  	if (old_pattern){
  	    regfree (&r);
- 	    g_free (old_pattern);
+ 	    mhl_mem_free (old_pattern);
  	    old_pattern = NULL;
  	}
  	my_pattern = convert_pattern (pattern, match_type, 0);
  	if (regcomp (&r, my_pattern, REG_EXTENDED|REG_NOSUB|MC_ARCH_FLAGS)) {
- 	    g_free (my_pattern);
+ 	    mhl_mem_free (my_pattern);
  	    return -1;
  	}
  	old_pattern = my_pattern;
@@@ -634,7 -628,7 +635,7 @@@ set_int (const char *file, const char *
  {
      char buffer [BUF_TINY];
  
 -    g_snprintf (buffer, sizeof (buffer), "%d", value);
 +    snprintf (buffer, sizeof (buffer), "%d", value);
      return WritePrivateProfileString (app_text, key, buffer, file);
  }
  
@@@ -643,7 -637,7 +644,7 @@@ get_config_string (const char *file, co
  {
      char buffer[1024];
      (void)GetPrivateProfileString (app_text, key, defval, buffer, sizeof(buffer), file);
 -    return g_strdup (buffer);
 +    return mhl_str_dup (buffer);
  }
  
  extern void
@@@ -681,7 -675,7 +682,7 @@@ load_file (const char *filename
      if (read_size > 0)
  	return data;
      else {
- 	 g_free (data);
+ 	 mhl_mem_free (data);
  	return 0;
      }
  }
@@@ -693,14 -687,14 +694,14 @@@ load_mc_home_file (const char *filename
      char *lang;
      char *data;
  
 -    hintfile_base = concat_dir_and_file (mc_home, filename);
 +    hintfile_base = mhl_str_dir_plus_file (mc_home, filename);
      lang = guess_message_value ();
  
      hintfile = g_strconcat (hintfile_base, ".", lang, (char *) NULL);
      data = load_file (hintfile);
  
      if (!data) {
- 	g_free (hintfile);
+ 	mhl_mem_free (hintfile);
  	/* Fall back to the two-letter language code */
  	if (lang[0] && lang[1])
  	    lang[2] = 0;
@@@ -708,21 -702,21 +709,21 @@@
  	data = load_file (hintfile);
  
  	if (!data) {
- 	    g_free (hintfile);
+ 	    mhl_mem_free (hintfile);
  	    hintfile = hintfile_base;
  	    data = load_file (hintfile_base);
  	}
      }
  
-     g_free (lang);
+     mhl_mem_free (lang);
  
      if (hintfile != hintfile_base)
- 	g_free (hintfile_base);
+ 	mhl_mem_free (hintfile_base);
  
      if (allocated_filename)
  	*allocated_filename = hintfile;
      else
- 	g_free (hintfile);
+ 	mhl_mem_free (hintfile);
  
      return data;
  }
@@@ -850,11 -844,11 +851,11 @@@ unix_error_string (int error_num
      gchar *strerror_currentlocale;
  	
      strerror_currentlocale = g_locale_from_utf8(g_strerror (error_num), -1, NULL, NULL, NULL);
 -    g_snprintf (buffer, sizeof (buffer), "%s (%d)",
 +    snprintf (buffer, sizeof (buffer), "%s (%d)",
  		strerror_currentlocale, error_num);
-     g_free(strerror_currentlocale);
+     mhl_mem_free(strerror_currentlocale);
  #else
 -    g_snprintf (buffer, sizeof (buffer), "%s (%d)",
 +    snprintf (buffer, sizeof (buffer), "%s (%d)",
  		g_strerror (error_num), error_num);
  #endif
      return buffer;
@@@ -937,12 -931,12 +938,12 @@@ get_current_wd (char *buffer, int size
      len = strlen(p) + 1;
  
      if (len > size) {
- 	g_free (p);
+ 	mhl_mem_free (p);
  	return NULL;
      }
  
      memcpy (buffer, p, len);
-     g_free (p);
+     mhl_mem_free (p);
  
      return buffer;
  }
@@@ -1048,7 -1042,7 +1049,7 @@@ execute_hooks (Hook *hook_list
      for (hook_list = p; hook_list;){
  	p = hook_list;
  	hook_list = hook_list->next;
- 	 g_free (p);
+ 	 mhl_mem_free (p);
      }
  }
  
@@@ -1062,7 -1056,7 +1063,7 @@@ delete_hook (Hook **hook_list, void (*h
      for (current = *hook_list; current; current = next){
  	next = current->next;
  	if (current->hook_fn == hook_fn)
- 	    g_free (current);
+ 	    mhl_mem_free (current);
  	else
  	    add_hook (&new_list, current->hook_fn, current->hook_data);
      }
@@@ -1089,7 -1083,7 +1090,7 @@@ wipe_password (char *passwd
  	return;
      for (;*p ; p++)
          *p = 0;
-     g_free (passwd);
+     mhl_mem_free (passwd);
  }
  
  /* Convert "\E" -> esc character and ^x to control-x key and ^^ to ^ key */
@@@ -1097,7 -1091,7 +1098,7 @@@
  char *
  convert_controls (const char *p)
  {
 -    char *valcopy = g_strdup (p);
 +    char *valcopy = mhl_str_dup (p);
      char *q;
  
      /* Parse the escape special character */
@@@ -1154,8 -1148,8 +1155,8 @@@ resolve_symlinks (const char *path
  	c = *q;
  	*q = 0;
  	if (mc_lstat (path, &mybuf) < 0) {
- 	    g_free (buf);
- 	    g_free (buf2);
+ 	    mhl_mem_free (buf);
+ 	    mhl_mem_free (buf2);
  	    *q = c;
  	    return NULL;
  	}
@@@ -1164,8 -1158,8 +1165,8 @@@
  	else {
  	    len = mc_readlink (path, buf2, MC_MAXPATHLEN - 1);
  	    if (len < 0) {
- 		g_free (buf);
- 		g_free (buf2);
+ 		mhl_mem_free (buf);
+ 		mhl_mem_free (buf2);
  		*q = c;
  		return NULL;
  	    }
@@@ -1190,7 -1184,7 +1191,7 @@@
  	strcpy (buf, PATH_SEP_STR);
      else if (*(r - 1) == PATH_SEP && r != buf + 1)
  	*(r - 1) = 0;
-     g_free (buf2);
+     mhl_mem_free (buf2);
      return buf;
  }
  
@@@ -1208,7 -1202,7 +1209,7 @@@ diff_two_paths (const char *first, cons
          return NULL;
      my_second = resolve_symlinks (second);
      if (my_second == NULL) {
- 	g_free (my_first);
+ 	mhl_mem_free (my_first);
  	return NULL;
      }
      for (j = 0; j < 2; j++) {
@@@ -1234,10 -1228,10 +1235,10 @@@
  	currlen = (i + 1) * 3 + strlen (q) + 1;
  	if (j) {
  	    if (currlen < prevlen)
- 	        g_free (buf);
+ 	        mhl_mem_free (buf);
  	    else {
- 		g_free (my_first);
- 		g_free (my_second);
+ 		mhl_mem_free (my_first);
+ 		mhl_mem_free (my_second);
  		return buf;
  	    }
  	}
@@@ -1247,11 -1241,23 +1248,11 @@@
  	    strcpy (p, "../");
  	strcpy (p, q);
      }
-     g_free (my_first);
-     g_free (my_second);
+     mhl_mem_free (my_first);
+     mhl_mem_free (my_second);
      return buf;
  }
  
 -/* If filename is NULL, then we just append PATH_SEP to the dir */
 -char *
 -concat_dir_and_file (const char *dir, const char *file)
 -{
 -    int i = strlen (dir);
 -    
 -    if (dir [i-1] == PATH_SEP)
 -	return  g_strconcat (dir, file, (char *) NULL);
 -    else
 -	return  g_strconcat (dir, PATH_SEP_STR, file, (char *) NULL);
 -}
 -
  /* Append text to GList, remove all entries with the same text */
  GList *
  list_append_unique (GList *list, char *text)
@@@ -1270,7 -1276,7 +1271,7 @@@
      while (link) {
  	newlink = g_list_previous (link);
  	if (!strcmp ((char *) link->data, text)) {
- 	    g_free (link->data);
+ 	    mhl_mem_free (link->data);
  	    g_list_remove_link (list, link);
  	    g_list_free_1 (link);
  	}
@@@ -1289,7 -1295,7 +1290,7 @@@
  
  /*
   * Arguments:
-  * pname (output) - pointer to the name of the temp file (needs g_free).
+  * pname (output) - pointer to the name of the temp file (needs mhl_mem_free).
   *                  NULL if the function fails.
   * prefix - part of the filename before the random part.
   *          Prepend $TMPDIR or /tmp if there are no path separators.
@@@ -1312,15 -1318,15 +1313,15 @@@ mc_mkstemps (char **pname, const char *
  
      if (strchr (prefix, PATH_SEP) == NULL) {
  	/* Add prefix first to find the position of XXXXXX */
 -	tmpbase = concat_dir_and_file (mc_tmpdir (), prefix);
 +	tmpbase = mhl_str_dir_plus_file (mc_tmpdir (), prefix);
      } else {
 -	tmpbase = g_strdup (prefix);
 +	tmpbase = mhl_str_dup (prefix);
      }
  
      tmpname = g_strconcat (tmpbase, "XXXXXX", suffix, (char *) NULL);
      *pname = tmpname;
      XXXXXX = &tmpname[strlen (tmpbase)];
-     g_free (tmpbase);
+     mhl_mem_free (tmpbase);
  
      /* Get some more or less random data.  */
      gettimeofday (&tv, NULL);
@@@ -1357,7 -1363,7 +1358,7 @@@
      }
  
      /* Unsuccessful. Free the filename. */
-     g_free (tmpname);
+     mhl_mem_free (tmpname);
      *pname = NULL;
  
      return -1;
@@@ -1380,9 -1386,9 +1381,9 @@@ load_file_position (const char *filenam
      *column = 0;
  
      /* open file with positions */
 -    fn = concat_dir_and_file (home_dir, MC_FILEPOS);
 +    fn = mhl_str_dir_plus_file (home_dir, MC_FILEPOS);
      f = fopen (fn, "r");
-     g_free (fn);
+     mhl_mem_free (fn);
      if (!f)
  	return;
  
@@@ -1427,14 -1433,14 +1428,14 @@@ save_file_position (const char *filenam
  
      len = strlen (filename);
  
 -    tmp = concat_dir_and_file (home_dir, MC_FILEPOS_TMP);
 -    fn = concat_dir_and_file (home_dir, MC_FILEPOS);
 +    tmp = mhl_str_dir_plus_file (home_dir, MC_FILEPOS_TMP);
 +    fn = mhl_str_dir_plus_file (home_dir, MC_FILEPOS);
  
      /* open temporary file */
      t = fopen (tmp, "w");
      if (!t) {
- 	g_free (tmp);
- 	g_free (fn);
+ 	mhl_mem_free (tmp);
+ 	mhl_mem_free (fn);
  	return;
      }
  
@@@ -1461,8 -1467,8 +1462,8 @@@
  
      fclose (t);
      rename (tmp, fn);
-     g_free (tmp);
-     g_free (fn);
+     mhl_mem_free (tmp);
+     mhl_mem_free (fn);
  }
  
  extern const char *
@@@ -1521,3 -1527,4 +1522,3 @@@ Q_ (const char *s
      sep = strchr(result, '|');
      return (sep != NULL) ? sep + 1 : result;
  }
 -
diff --combined src/utilunix.c
index b550f44,e94d132..5dfa18e
--- a/src/utilunix.c
+++ b/src/utilunix.c
@@@ -41,8 -41,7 +41,9 @@@
  #endif
  #include <unistd.h>
  
 +#include <mhl/types.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "execute.h"
@@@ -74,8 -73,8 +75,8 @@@ static char *i_cache_match (int id, int
  static void i_cache_add (int id, int_cache *cache, int size, char *text,
  			 int *last)
  {
-     g_free (cache [*last].string);
+     mhl_mem_free (cache [*last].string);
 -    cache [*last].string = g_strdup (text);
 +    cache [*last].string = mhl_str_dup (text);
      cache [*last].index = id;
      *last = ((*last)+1) % size;
  }
@@@ -96,7 -95,7 +97,7 @@@ char *get_owner (int uid
  	return pwd->pw_name;
      }
      else {
 -	g_snprintf (ibuf, sizeof (ibuf), "%d", uid);
 +	snprintf (ibuf, sizeof (ibuf), "%d", uid);
  	return ibuf;
      }
  }
@@@ -116,7 -115,7 +117,7 @@@ char *get_group (int gid
  	i_cache_add (gid, gid_cache, GID_CACHE_SIZE, grp->gr_name, &gid_last);
  	return grp->gr_name;
      } else {
 -	g_snprintf (gbuf, sizeof (gbuf), "%d", gid);
 +	snprintf (gbuf, sizeof (gbuf), "%d", gid);
  	return gbuf;
      }
  }
@@@ -189,7 -188,7 +190,7 @@@ tilde_expand (const char *directory
      char *name;
  
      if (*directory != '~')
 -	return g_strdup (directory);
 +	return mhl_str_dup (directory);
  
      p = directory + 1;
  
@@@ -205,13 -204,13 +206,13 @@@
  	    name = g_strndup (p, q - p);
  	    passwd = getpwnam (name);
  	    q++;
- 	    g_free (name);
+ 	    mhl_mem_free (name);
  	}
      }
  
      /* If we can't figure the user name, leave tilde unexpanded */
      if (!passwd)
 -	return g_strdup (directory);
 +	return mhl_str_dup (directory);
  
      return g_strconcat (passwd->pw_dir, PATH_SEP_STR, q, (char *) NULL);
  }
@@@ -257,10 -256,10 +258,10 @@@ mc_tmpdir (void
      pwd = getpwuid (getuid ());
  
      if (pwd)
 -	g_snprintf (buffer, sizeof (buffer), "%s/mc-%s", sys_tmp,
 +	snprintf (buffer, sizeof (buffer), "%s/mc-%s", sys_tmp,
  		pwd->pw_name);
      else
 -	g_snprintf (buffer, sizeof (buffer), "%s/mc-%lu", sys_tmp,
 +	snprintf (buffer, sizeof (buffer), "%s/mc-%lu", sys_tmp,
  		(unsigned long) getuid ());
  
      canonicalize_pathname (buffer);
@@@ -295,7 -294,7 +296,7 @@@
  	/* Test if sys_tmp is suitable for temporary files */
  	fallback_prefix = g_strdup_printf ("%s/mctest", sys_tmp);
  	test_fd = mc_mkstemps (&test_fn, fallback_prefix, NULL);
- 	g_free (fallback_prefix);
+ 	mhl_mem_free (fallback_prefix);
  	if (test_fd != -1) {
  	    close (test_fd);
  	    test_fd = open (test_fn, O_RDONLY);
@@@ -309,11 -308,11 +310,11 @@@
  	if (fallback_ok) {
  	    fprintf (stderr, _("Temporary files will be created in %s\n"),
  		     sys_tmp);
 -	    g_snprintf (buffer, sizeof (buffer), "%s", sys_tmp);
 +	    snprintf (buffer, sizeof (buffer), "%s", sys_tmp);
  	    error = NULL;
  	} else {
  	    fprintf (stderr, _("Temporary files will not be created\n"));
 -	    g_snprintf (buffer, sizeof (buffer), "%s", "/dev/null/");
 +	    snprintf (buffer, sizeof (buffer), "%s", "/dev/null/");
  	}
  
  	fprintf (stderr, "%s\n", _("Press any key to continue..."));
@@@ -429,7 -428,7 +430,7 @@@ canonicalize_pathname (char *path
  	if (p[0] == PATH_SEP && p[1] == PATH_SEP) {
  	    s = p + 1;
  	    while (*(++s) == PATH_SEP);
 -	    strcpy (p + 1, s);
 +	    mhl_strmove (p + 1, s);
  	}
  	p++;
      }
@@@ -438,7 -437,7 +439,7 @@@
      p = lpath;
      while (*p) {
  	if (p[0] == PATH_SEP && p[1] == '.' && p[2] == PATH_SEP)
 -	    strcpy (p, p + 2);
 +	    mhl_strmove (p, p + 2);
  	else
  	    p++;
      }
@@@ -454,7 -453,7 +455,7 @@@
  	    lpath[1] = 0;
  	    return;
  	} else {
 -	    strcpy (lpath, lpath + 2);
 +	    mhl_strmove (lpath, lpath + 2);
  	}
      }
  
@@@ -500,10 -499,10 +501,10 @@@
  	if (p[3] != 0) {
  	    if (s == lpath && *s == PATH_SEP) {
  		/* "/../foo" -> "/foo" */
 -		strcpy (s + 1, p + 4);
 +		mhl_strmove (s + 1, p + 4);
  	    } else {
  		/* "token/../foo" -> "foo" */
 -		strcpy (s, p + 4);
 +		mhl_strmove (s, p + 4);
  	    }
  	    p = (s > lpath) ? s - 1 : s;
  	    continue;
@@@ -722,7 -721,7 +723,7 @@@ mc_realpath (const char *path, char res
  /* Return the index of the permissions triplet */
  int
  get_user_permissions (struct stat *st) {
 -    static gboolean initialized = FALSE;
 +    static bool initialized = FALSE;
      static gid_t *groups;
      static int ngroups;
      static uid_t uid;
diff --combined src/view.c
index 5a3de16,19fe959..dcd3559
--- a/src/view.c
+++ b/src/view.c
@@@ -43,8 -43,7 +43,9 @@@
  #include <sys/stat.h>
  #include <unistd.h>
  
 +#include <mhl/types.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -144,23 -143,23 +145,23 @@@ struct WView 
      size_t ds_string_len;	/* The length of the string */
  
      /* Growing buffers information */
 -    gboolean growbuf_in_use;	/* Use the growing buffers? */
 +    bool growbuf_in_use;	/* Use the growing buffers? */
      byte   **growbuf_blockptr;	/* Pointer to the block pointers */
      size_t   growbuf_blocks;	/* The number of blocks in *block_ptr */
      size_t   growbuf_lastindex;	/* Number of bytes in the last page of the
  				   growing buffer */
 -    gboolean growbuf_finished;	/* TRUE when all data has been read. */
 +    bool growbuf_finished;	/* TRUE when all data has been read. */
  
      /* Editor modes */
 -    gboolean hex_mode;		/* Hexview or Hexedit */
 -    gboolean hexedit_mode;	/* Hexedit */
 -    gboolean hexview_in_text;	/* Is the hexview cursor in the text area? */
 -    gboolean text_nroff_mode;	/* Nroff-style highlighting */
 -    gboolean text_wrap_mode;	/* Wrap text lines to fit them on the screen */
 -    gboolean magic_mode;	/* Preprocess the file using external programs */
 +    bool hex_mode;		/* Hexview or Hexedit */
 +    bool hexedit_mode;	/* Hexedit */
 +    bool hexview_in_text;	/* Is the hexview cursor in the text area? */
 +    bool text_nroff_mode;	/* Nroff-style highlighting */
 +    bool text_wrap_mode;	/* Wrap text lines to fit them on the screen */
 +    bool magic_mode;	/* Preprocess the file using external programs */
  
      /* Additional editor state */
 -    gboolean hexedit_lownibble;	/* Are we editing the last significant nibble? */
 +    bool hexedit_lownibble;	/* Are we editing the last significant nibble? */
      GArray *coord_cache;	/* Cache for mapping offsets to cursor positions */
  
      /* Display information */
@@@ -178,7 -177,7 +179,7 @@@
      struct area data_area;	/* Where the data is displayed */
  
      int dirty;			/* Number of skipped updates */
 -    gboolean dpy_bbar_dirty;	/* Does the button bar need to be updated? */
 +    bool dpy_bbar_dirty;	/* Does the button bar need to be updated? */
  
      /* Mode variables */
      int bytes_per_line;		/* Number of bytes per line in hex mode */
@@@ -190,7 -189,7 +191,7 @@@
      int  direction;		/* 1= forward; -1 backward */
      void (*last_search)(WView *);
  				/* Pointer to the last search command */
 -    gboolean want_to_quit;	/* Prepare for cleanup ... */
 +    bool want_to_quit;	/* Prepare for cleanup ... */
  
      /* Markers */
      int marker;			/* mark to use */
@@@ -281,7 -280,7 +282,7 @@@ offset_rounddown (offset_type a, offset
  
  /* {{{ Simple Primitive Functions for WView }}} */
  
 -static inline gboolean
 +static inline bool
  view_is_in_panel (WView *view)
  {
      return (view->dpy_frame_size != 0);
@@@ -348,7 -347,7 +349,7 @@@ view_hexedit_free_change_list (WView *v
  
      for (curr = view->change_list; curr != NULL; curr = next) {
  	next = curr->next;
- 	g_free (curr);
+ 	mhl_mem_free (curr);
      }
      view->change_list = NULL;
      view->dirty++;
@@@ -374,8 -373,8 +375,8 @@@ view_growbuf_free (WView *view
      assert (view->growbuf_in_use);
  
      for (i = 0; i < view->growbuf_blocks; i++)
- 	g_free (view->growbuf_blockptr[i]);
-     g_free (view->growbuf_blockptr);
+ 	mhl_mem_free (view->growbuf_blockptr[i]);
+     mhl_mem_free (view->growbuf_blockptr);
      view->growbuf_blockptr = NULL;
      view->growbuf_in_use = FALSE;
  }
@@@ -401,7 -400,7 +402,7 @@@ view_growbuf_read_until (WView *view, o
      ssize_t nread;
      byte *p;
      size_t bytesfree;
 -    gboolean short_read;
 +    bool short_read;
  
      assert (view->growbuf_in_use);
  
@@@ -415,12 -414,12 +416,12 @@@
  	    byte *newblock = g_try_malloc (VIEW_PAGE_SIZE);
  	    byte **newblocks = g_try_malloc (sizeof (*newblocks) * (view->growbuf_blocks + 1));
  	    if (!newblock || !newblocks) {
- 		g_free (newblock);
- 		g_free (newblocks);
+ 		mhl_mem_free (newblock);
+ 		mhl_mem_free (newblocks);
  		return;
  	    }
  	    memcpy (newblocks, view->growbuf_blockptr, sizeof (*newblocks) * view->growbuf_blocks);
- 	    g_free (view->growbuf_blockptr);
+ 	    mhl_mem_free (view->growbuf_blockptr);
  	    view->growbuf_blockptr = newblocks;
  	    view->growbuf_blockptr[view->growbuf_blocks++] = newblock;
  	    view->growbuf_lastindex = 0;
@@@ -516,7 -515,7 +517,7 @@@ view_get_filesize (WView *view
      }
  }
  
 -static inline gboolean
 +static inline bool
  view_may_still_grow (WView *view)
  {
      return (view->growbuf_in_use && !view->growbuf_finished);
@@@ -525,7 -524,7 +526,7 @@@
  /* returns TRUE if the idx lies in the half-open interval
   * [offset; offset + size), FALSE otherwise.
   */
 -static inline gboolean
 +static inline bool
  already_loaded (offset_type offset, offset_type idx, size_t size)
  {
      return (offset <= idx && idx - offset < size);
@@@ -666,7 -665,7 +667,7 @@@ static voi
  view_set_datasource_string (WView *view, const char *s)
  {
      view->datasource = DS_STRING;
 -    view->ds_string_data = (byte *) g_strdup (s);
 +    view->ds_string_data = (byte *) mhl_str_dup (s);
      view->ds_string_len  = strlen (s);
  }
  
@@@ -707,11 -706,11 +708,11 @@@ view_close_datasource (WView *view
  	case DS_FILE:
  	    (void) mc_close (view->ds_file_fd);
  	    view->ds_file_fd = -1;
- 	    g_free (view->ds_file_data);
+ 	    mhl_mem_free (view->ds_file_data);
  	    view->ds_file_data = NULL;
  	    break;
  	case DS_STRING:
- 	    g_free (view->ds_string_data);
+ 	    mhl_mem_free (view->ds_string_data);
  	    view->ds_string_data = NULL;
  	    break;
  	default:
@@@ -741,10 -740,10 +742,10 @@@ enum ccache_type 
      CCACHE_LINECOL
  };
  
 -static inline gboolean
 +static inline bool
  coord_cache_entry_less (const struct coord_cache_entry *a,
  	const struct coord_cache_entry *b, enum ccache_type crit,
 -	gboolean nroff_mode)
 +	bool nroff_mode)
  {
      if (crit == CCACHE_OFFSET)
  	return (a->cc_offset < b->cc_offset);
@@@ -830,7 -829,7 +831,7 @@@ view_ccache_dump (WView *view
  }
  #endif
  
 -static inline gboolean
 +static inline bool
  is_nroff_sequence (WView *view, offset_type offset)
  {
      int c0, c1, c2;
@@@ -1090,7 -1089,7 +1091,7 @@@ view_scroll_to_cursor (WView *view
  }
  
  static void
 -view_movement_fixups (WView *view, gboolean reset_search)
 +view_movement_fixups (WView *view, bool reset_search)
  {
      view_scroll_to_cursor (view);
      if (reset_search) {
@@@ -1394,13 -1393,13 +1395,13 @@@ view_toggle_magic_mode (WView *view
  
      altered_magic_flag = 1;
      view->magic_mode = !view->magic_mode;
 -    filename = g_strdup (view->filename);
 -    command = g_strdup (view->command);
 +    filename = mhl_str_dup (view->filename);
 +    command = mhl_str_dup (view->command);
  
      view_done (view);
      view_load (view, command, filename, 0);
-     g_free (filename);
-     g_free (command);
+     mhl_mem_free (filename);
+     mhl_mem_free (command);
      view->dpy_bbar_dirty = TRUE;
      view->dirty++;
  }
@@@ -1418,7 -1417,7 +1419,7 @@@ view_done (WView *view
  	canon_fname = vfs_canon (view->filename);
  	view_offset_to_coord (view, &line, &col, view->dpy_start);
  	save_file_position (canon_fname, line + 1, col);
- 	g_free (canon_fname);
+ 	mhl_mem_free (canon_fname);
      }
  
      /* Write back the global viewer mode */
@@@ -1431,8 -1430,8 +1432,8 @@@
  
      /* view->widget needs no destructor */
  
-     g_free (view->filename), view->filename = NULL;
-     g_free (view->command), view->command = NULL;
+     mhl_mem_free (view->filename), view->filename = NULL;
+     mhl_mem_free (view->command), view->command = NULL;
  
      view_close_datasource (view);
      /* the growing buffer is freed with the datasource */
@@@ -1456,7 -1455,7 +1457,7 @@@ view_show_error (WView *view, const cha
      }
  }
  
 -static gboolean
 +static bool
  view_load_command_output (WView *view, const char *command)
  {
      FILE *fp;
@@@ -1486,7 -1485,7 +1487,7 @@@
      return TRUE;
  }
  
 -gboolean
 +bool
  view_load (WView *view, const char *command, const char *file,
  	   int start_line)
  {
@@@ -1494,14 -1493,14 +1495,14 @@@
      int fd = -1;
      char tmp[BUF_MEDIUM];
      struct stat st;
 -    gboolean retval = FALSE;
 +    bool retval = FALSE;
  
      assert (view->bytes_per_line != 0);
      view_done (view);
  
      /* Set up the state */
      view_set_datasource_none (view);
 -    view->filename = g_strdup (file);
 +    view->filename = mhl_str_dup (file);
      view->command = 0;
  
      /* Clear the markers */
@@@ -1518,7 -1517,7 +1519,7 @@@
      } else if (file != NULL && file[0] != '\0') {
  	/* Open the file */
  	if ((fd = mc_open (file, O_RDONLY | O_NONBLOCK)) == -1) {
 -	    g_snprintf (tmp, sizeof (tmp), _(" Cannot open \"%s\"\n %s "),
 +	    snprintf (tmp, sizeof (tmp), _(" Cannot open \"%s\"\n %s "),
  			file, unix_error_string (errno));
  	    view_show_error (view, tmp);
  	    goto finish;
@@@ -1527,7 -1526,7 +1528,7 @@@
  	/* Make sure we are working with a regular file */
  	if (mc_fstat (fd, &st) == -1) {
  	    mc_close (fd);
 -	    g_snprintf (tmp, sizeof (tmp), _(" Cannot stat \"%s\"\n %s "),
 +	    snprintf (tmp, sizeof (tmp), _(" Cannot stat \"%s\"\n %s "),
  			file, unix_error_string (errno));
  	    view_show_error (view, tmp);
  	    goto finish;
@@@ -1546,7 -1545,7 +1547,7 @@@
  	    type = get_compression_type (fd);
  
  	    if (view->magic_mode && (type != COMPRESSION_NONE)) {
- 		g_free (view->filename);
+ 		mhl_mem_free (view->filename);
  		view->filename = g_strconcat (file, decompress_extension (type), (char *) NULL);
  	    }
  	    view_set_datasource_file (view, fd, &st);
@@@ -1555,7 -1554,7 +1556,7 @@@
      }
  
    finish:
 -    view->command = g_strdup (command);
 +    view->command = mhl_str_dup (command);
      view->dpy_start = 0;
      view->search_start = 0;
      view->search_length = 0;
@@@ -1569,7 -1568,7 +1570,7 @@@
  
  	canon_fname = vfs_canon (file);
  	load_file_position (file, &line, &col);
- 	g_free (canon_fname);
+ 	mhl_mem_free (canon_fname);
  	view_moveto (view, offset_doz(line, 1), col);
      } else if (start_line > 0) {
  	view_moveto (view, start_line - 1, 0);
@@@ -1743,7 -1742,7 +1744,7 @@@ view_display_ruler (WView *view
  	}
  
  	if ((cl != 0) && (cl % 10) == 0) {
 -	    g_snprintf (r_buff, sizeof (r_buff), "%"OFFSETTYPE_PRId, cl);
 +	    snprintf (r_buff, sizeof (r_buff), "%"OFFSETTYPE_PRId, cl);
  	    if (nums_row < height) {
  		widget_move (view, top + nums_row, left + c - 1);
  		tty_print_string (r_buff);
@@@ -1791,7 -1790,7 +1792,7 @@@ view_display_hex (WView *view
  	col = 0;
  
  	/* Print the hex offset */
 -	g_snprintf (hex_buff, sizeof (hex_buff), "%08"OFFSETTYPE_PRIX" ", from);
 +	snprintf (hex_buff, sizeof (hex_buff), "%08"OFFSETTYPE_PRIX" ", from);
  	widget_move (view, top + row, left);
  	tty_setcolor (MARKED_COLOR);
  	for (i = 0; col < width && hex_buff[i] != '\0'; i++) {
@@@ -2138,7 -2137,7 +2139,7 @@@ view_handle_editkey (WView *view, int k
      return MSG_HANDLED;
  }
  
 -static gboolean
 +static bool
  view_hexedit_save_changes (WView *view)
  {
      struct hexedit_change_node *curr, *next;
@@@ -2165,28 -2164,28 +2166,28 @@@
  	view->change_list = next;
  	view->dirty++;
  	view_set_byte (view, curr->offset, curr->value);
- 	g_free (curr);
+ 	mhl_mem_free (curr);
      }
  
      if (mc_close (fp) == -1) {
 -	error = g_strdup (strerror (errno));
 +	error = mhl_str_dup (strerror (errno));
  	message (D_ERROR, _(" Save file "),
  	    _(" Error while closing the file: \n %s \n"
  	      " Data may have been written or not. "), error);
- 	g_free (error);
+ 	mhl_mem_free (error);
      }
      view_update (view);
      return TRUE;
  
    save_error:
 -    error = g_strdup (strerror (errno));
 +    error = mhl_str_dup (strerror (errno));
      text = g_strdup_printf (_(" Cannot save file: \n %s "), error);
-     g_free (error);
+     mhl_mem_free (error);
      (void) mc_close (fp);
  
      answer = query_dialog (_(" Save file "), text, D_ERROR,
  	2, _("&Retry"), _("&Cancel"));
-     g_free (text);
+     mhl_mem_free (text);
  
      if (answer == 0)
  	goto retry_save;
@@@ -2195,7 -2194,7 +2196,7 @@@
  
  /* {{{ Miscellaneous functions }}} */
  
 -static gboolean
 +static bool
  view_ok_to_quit (WView *view)
  {
      int r;
@@@ -2391,7 -2390,7 +2392,7 @@@ search (WView *view, char *text
      view->update_activate = 0;
  
      enable_interrupt_key ();
-     for (;; g_free (s)) {
+     for (;; mhl_mem_free (s)) {
  	if (p >= view->update_activate) {
  	    view->update_activate += view->update_steps;
  	    if (verbose) {
@@@ -2410,7 -2409,7 +2411,7 @@@
  
  	search_status = (*search) (view, text, s + 1, match_normal);
  	if (search_status < 0) {
- 	    g_free (s);
+ 	    mhl_mem_free (s);
  	    break;
  	}
  
@@@ -2438,7 -2437,7 +2439,7 @@@
  	    view->dpy_start = t;
  	}
  
- 	g_free (s);
+ 	mhl_mem_free (s);
  	break;
      }
      disable_interrupt_key ();
@@@ -2599,7 -2598,7 +2600,7 @@@ hex_search (WView *view, const char *te
      /* No valid bytes in the user input */
      if (block_len <= 0 || parse_error) {
  	message (D_NORMAL, _("Search"), _("Invalid hex search expression"));
- 	g_free (buffer);
+ 	mhl_mem_free (buffer);
  	view->search_length = 0;
  	return;
      }
@@@ -2607,7 -2606,7 +2608,7 @@@
      /* Then start the search */
      pos = block_search (view, buffer, block_len);
  
-     g_free (buffer);
+     mhl_mem_free (buffer);
  
      if (pos == INVALID_OFFSET) {
  	message (D_NORMAL, _("Search"), _(" Search string not found "));
@@@ -2639,7 -2638,7 +2640,7 @@@ regexp_view_search (WView *view, char *
  	|| old_type != match_type) {
  	if (old_pattern != NULL) {
  	    regfree (&r);
- 	    g_free (old_pattern);
+ 	    mhl_mem_free (old_pattern);
  	    old_pattern = 0;
  	}
  	for (i = 0; pattern[i] != '\0'; i++) {
@@@ -2653,7 -2652,7 +2654,7 @@@
  	    message (D_ERROR, MSG_ERROR, _(" Invalid regular expression "));
  	    return -1;
  	}
 -	old_pattern = g_strdup (pattern);
 +	old_pattern = mhl_str_dup (pattern);
  	old_type = match_type;
      }
      if (regexec (&r, string, 1, pmatch, 0) != 0)
@@@ -2733,7 -2732,7 +2734,7 @@@ view_moveto_line_cmd (WView *view
  
      view_offset_to_coord (view, &line, &col, view->dpy_start);
  
 -    g_snprintf (prompt, sizeof (prompt),
 +    snprintf (prompt, sizeof (prompt),
  		_(" The current line number is %d.\n"
  		  " Enter the new line number:"), (int) (line + 1));
      answer = input_dialog (_(" Goto line "), prompt, MC_HISTORY_VIEW_GOTO_LINE, "");
@@@ -2743,7 -2742,7 +2744,7 @@@
  	if (*answer_end == '\0' && errno == 0 && line >= 1)
  	    view_moveto (view, line - 1, 0);
      }
-     g_free (answer);
+     mhl_mem_free (answer);
      view->dirty++;
      view_update (view);
  }
@@@ -2754,7 -2753,7 +2755,7 @@@ view_moveto_addr_cmd (WView *view
      char *line, *error, prompt[BUF_SMALL];
      offset_type addr;
  
 -    g_snprintf (prompt, sizeof (prompt),
 +    snprintf (prompt, sizeof (prompt),
  		_(" The current address is 0x%lx.\n"
  		  " Enter the new address:"), view->hex_cursor);
      line = input_dialog (_(" Goto Address "), prompt, MC_HISTORY_VIEW_GOTO_ADDR, "");
@@@ -2767,7 -2766,7 +2768,7 @@@
  		message (D_ERROR, _("Warning"), _(" Invalid address "));
  	    }
  	}
- 	g_free (line);
+ 	mhl_mem_free (line);
      }
      view->dirty++;
      view_update (view);
@@@ -2792,11 -2791,11 +2793,11 @@@ regexp_search (WView *view, int directi
  
      regexp = input_dialog (_("Search"), _(" Enter regexp:"), MC_HISTORY_VIEW_SEARCH_REGEX, defval);
      if (regexp == NULL || regexp[0] == '\0') {
- 	g_free (regexp);
+ 	mhl_mem_free (regexp);
  	return;
      }
  
-     g_free (last_regexp);
+     mhl_mem_free (last_regexp);
      view->search_exp = last_regexp = regexp;
  
      view->direction = direction;
@@@ -2848,7 -2847,7 +2849,7 @@@ view_normal_search_cmd (WView *view
  	"[Input Line Keys]", quick_widgets, 0
      };
  
 -    defval = g_strdup (last_search_string != NULL ? last_search_string : "");
 +    defval = mhl_str_dup (last_search_string != NULL ? last_search_string : "");
      convert_to_display (defval);
  
      quick_widgets[2].result = &treplace_backwards;
@@@ -2865,7 -2864,7 +2866,7 @@@
  
      convert_from_input (exp);
  
-     g_free (last_search_string);
+     mhl_mem_free (last_search_string);
      view->search_exp = last_search_string = exp;
      exp = NULL;
  
@@@ -2874,8 -2873,8 +2875,8 @@@
      view->last_search = do_normal_search;
  
  cleanup:
-     g_free (exp);
-     g_free (defval);
+     mhl_mem_free (exp);
+     mhl_mem_free (defval);
  }
  
  static void
@@@ -3319,7 -3318,7 +3320,7 @@@ in
  mc_internal_viewer (const char *command, const char *file,
  	int *move_dir_p, int start_line)
  {
 -    gboolean succeeded;
 +    bool succeeded;
      WView *wview;
      WButtonBar *bar;
      Dlg_head *view_dlg;
diff --combined src/widget.c
index 70f208e,7642d62..31afab6
--- a/src/widget.c
+++ b/src/widget.c
@@@ -34,8 -34,7 +34,9 @@@
  #include <string.h>
  #include <sys/types.h>
  
 +#include <mhl/types.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -44,6 -43,7 +45,6 @@@
  #include "dialog.h"
  #include "widget.h"
  #include "win.h"
 -#include "complete.h"
  #include "key.h"	/* XCTRL and ALT macros  */
  #include "profile.h"	/* for history loading and saving */
  #include "wtools.h"	/* For common_dialog_repaint() */
@@@ -70,7 -70,7 +71,7 @@@ static int button_event (Gpm_Event *eve
  int quote = 0;
  
  static void
 -widget_selectcolor (Widget *w, gboolean focused, gboolean hotkey)
 +widget_selectcolor (Widget *w, bool focused, bool hotkey)
  {
      Dlg_head *h = w->parent;
  
@@@ -158,15 -158,15 +159,15 @@@ button_callback (Widget *w, widget_msg_
  
  	switch (b->flags) {
  	case DEFPUSH_BUTTON:
 -	    g_snprintf (buf, sizeof (buf), "[< %s >]", b->text);
 +	    snprintf (buf, sizeof (buf), "[< %s >]", b->text);
  	    off = 3;
  	    break;
  	case NORMAL_BUTTON:
 -	    g_snprintf (buf, sizeof (buf), "[ %s ]", b->text);
 +	    snprintf (buf, sizeof (buf), "[ %s ]", b->text);
  	    off = 2;
  	    break;
  	case NARROW_BUTTON:
 -	    g_snprintf (buf, sizeof (buf), "[%s]", b->text);
 +	    snprintf (buf, sizeof (buf), "[%s]", b->text);
  	    off = 1;
  	    break;
  	case HIDDEN_BUTTON:
@@@ -189,7 -189,7 +190,7 @@@
  	return MSG_HANDLED;
  
      case WIDGET_DESTROY:
- 	g_free (b->text);
+ 	mhl_mem_free (b->text);
  	return MSG_HANDLED;
  
      default:
@@@ -263,7 -263,7 +264,7 @@@ button_new (int y, int x, int action, i
      b->action = action;
      b->flags  = flags;
      b->selected = 0;
 -    b->text   = g_strdup (text);
 +    b->text   = mhl_str_dup (text);
      b->callback = callback;
      widget_want_hotkey (b->widget, 1);
      b->hotkey = 0;
@@@ -282,8 -282,8 +283,8 @@@ button_get_text (WButton *b
  void
  button_set_text (WButton *b, const char *text)
  {
-    g_free (b->text);
 -   mhl_mem_free (b->text);
 -    b->text = g_strdup (text);
++    mhl_mem_free (b->text);
 +    b->text = mhl_str_dup (text);
      b->widget.cols = button_len (text, b->flags);
      button_scan_hotkey(b);
      dlg_redraw (b->widget.parent);
@@@ -359,7 -359,7 +360,7 @@@ radio_callback (Widget *w, widget_msg_
      case WIDGET_DRAW:
  	for (i = 0; i < r->count; i++) {
  	    register const char *cp;
 -	    const gboolean focused = (i == r->pos && msg == WIDGET_FOCUS);
 +	    const bool focused = (i == r->pos && msg == WIDGET_FOCUS);
  	    widget_selectcolor (w, focused, FALSE);
  	    widget_move (&r->widget, i, 0);
  
@@@ -475,7 -475,7 +476,7 @@@ check_callback (Widget *w, widget_msg_
  	return MSG_HANDLED;
  
      case WIDGET_DESTROY:
- 	g_free (c->text);
+ 	mhl_mem_free (c->text);
  	return MSG_HANDLED;
  
      default:
@@@ -513,7 -513,7 +514,7 @@@ check_new (int y, int x, int state, con
      init_widget (&c->widget, y, x, 1, strlen (text),
  	check_callback, check_event);
      c->state = state ? C_BOOL : 0;
 -    c->text = g_strdup (text);
 +    c->text = mhl_str_dup (text);
      c->hotkey = 0;
      c->hotpos = -1;
      widget_want_hotkey (c->widget, 1);
@@@ -587,7 -587,7 +588,7 @@@ label_callback (Widget *w, widget_msg_
  	}
  
      case WIDGET_DESTROY:
- 	g_free (l->text);
+ 	mhl_mem_free (l->text);
  	return MSG_HANDLED;
  
      default:
@@@ -603,10 -603,10 +604,10 @@@ label_set_text (WLabel *label, const ch
      if (label->text && text && !strcmp (label->text, text))
          return; /* Flickering is not nice */
  
-     g_free (label->text);
+     mhl_mem_free (label->text);
  
      if (text){
 -	label->text = g_strdup (text);
 +	label->text = mhl_str_dup (text);
  	if (label->auto_adjust_cols) {
  	    newcols = strlen (text);
  	    if (newcols > label->widget.cols)
@@@ -636,7 -636,7 +637,7 @@@ label_new (int y, int x, const char *te
  
      l = g_new (WLabel, 1);
      init_widget (&l->widget, y, x, 1, width, label_callback, NULL);
 -    l->text = text ? g_strdup (text) : 0;
 +    l->text = text ? mhl_str_dup (text) : 0;
      l->auto_adjust_cols = 1;
      l->transparent = 0;
      widget_want_cursor (l->widget, 0);
@@@ -867,19 -867,19 +868,19 @@@ history_get (const char *input_name
  	return NULL;
      if (!*input_name)
  	return NULL;
 -    profile = concat_dir_and_file (home_dir, HISTORY_FILE_NAME);
 +    profile = mhl_str_dir_plus_file (home_dir, HISTORY_FILE_NAME);
      for (i = 0;; i++) {
  	char key_name[BUF_TINY];
  	char this_entry[BUF_LARGE];
 -	g_snprintf (key_name, sizeof (key_name), "%d", i);
 +	snprintf (key_name, sizeof (key_name), "%d", i);
  	GetPrivateProfileString (input_name, key_name, "", this_entry,
  				 sizeof (this_entry), profile);
  	if (!*this_entry)
  	    break;
  
 -	hist = list_append_unique (hist, g_strdup (this_entry));
 +	hist = list_append_unique (hist, mhl_str_dup (this_entry));
      }
-     g_free (profile);
+     mhl_mem_free (profile);
  
      /* return pointer to the last entry in the list */
      hist = g_list_last (hist);
@@@ -905,14 -905,14 +906,14 @@@ history_put (const char *input_name, GL
      if (!num_history_items_recorded)	/* this is how to disable */
  	return;
  
 -    profile = concat_dir_and_file (home_dir, HISTORY_FILE_NAME);
 +    profile = mhl_str_dir_plus_file (home_dir, HISTORY_FILE_NAME);
  
      if ((i = open (profile, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) != -1)
  	close (i);
  
      /* Make sure the history is only readable by the user */
      if (chmod (profile, S_IRUSR | S_IWUSR) == -1 && errno != ENOENT) {
- 	g_free (profile);
+ 	mhl_mem_free (profile);
  	return;
      }
  
@@@ -935,13 -935,13 +936,13 @@@
  	/* We shouldn't have null entries, but let's be sure */
  	if (text && *text) {
  	    char key_name[BUF_TINY];
 -	    g_snprintf (key_name, sizeof (key_name), "%d", i++);
 +	    snprintf (key_name, sizeof (key_name), "%d", i++);
  	    WritePrivateProfileString (input_name, key_name, text,
  				       profile);
  	}
      }
  
-     g_free (profile);
+     mhl_mem_free (profile);
  }
  
  /* }}} history saving and loading */
@@@ -1040,7 -1040,7 +1041,7 @@@ show_hist (GList *history, int widget_x
      if (query_dlg->ret_value != B_CANCEL) {
  	listbox_get_current (query_list, &q, NULL);
  	if (q)
 -	    r = g_strdup (q);
 +	    r = mhl_str_dup (q);
      }
      destroy_dlg (query_dlg);
      return r;
@@@ -1052,7 -1052,7 +1053,7 @@@ static void do_show_hist (WInput * in
      r = show_hist (in->history, in->widget.x, in->widget.y);
      if (r) {
  	assign_text (in, r);
- 	g_free (r);
+ 	mhl_mem_free (r);
      }
  }
  
@@@ -1073,13 -1073,13 +1074,13 @@@ input_destroy (WInput *in
  	    history_put (in->history_name, in->history);
  
  	in->history = g_list_first (in->history);
- 	g_list_foreach (in->history, (GFunc) g_free, NULL);
+ 	g_list_foreach (in->history, (GFunc) mhl_mem_free, NULL);
  	g_list_free (in->history);
      }
  
-     g_free (in->buffer);
+     mhl_mem_free (in->buffer);
      free_completions (in);
-     g_free (in->history_name);
+     mhl_mem_free (in->history_name);
  }
  
  void
@@@ -1129,7 -1129,7 +1130,7 @@@ push_history (WInput *in, const char *t
  	    return 1;
      }
  
 -    t = g_strdup (text);
 +    t = mhl_str_dup (text);
  
      if (in->history_name) {
  	p = in->history_name + 3;
@@@ -1300,7 -1300,7 +1301,7 @@@ copy_region (WInput *in, int x_first, i
      if (last == first)
  	return;
      
-     g_free (kill_buffer);
+     mhl_mem_free (kill_buffer);
  
      kill_buffer = g_strndup(in->buffer+first,last-first);
  }
@@@ -1381,8 -1381,8 +1382,8 @@@ yank (WInput *in
  static void
  kill_line (WInput *in)
  {
-     g_free (kill_buffer);
+     mhl_mem_free (kill_buffer);
 -    kill_buffer = g_strdup (&in->buffer [in->point]);
 +    kill_buffer = mhl_str_dup (&in->buffer [in->point]);
      in->buffer [in->point] = 0;
  }
  
@@@ -1390,8 -1390,8 +1391,8 @@@ voi
  assign_text (WInput *in, const char *text)
  {
      free_completions (in);
-     g_free (in->buffer);
+     mhl_mem_free (in->buffer);
 -    in->buffer = g_strdup (text);	/* was in->buffer->text */
 +    in->buffer = mhl_str_dup (text);	/* was in->buffer->text */
      in->current_max_len = strlen (in->buffer) + 1;
      in->point = strlen (in->buffer);
      in->mark = 0;
@@@ -1660,7 -1660,7 +1661,7 @@@ input_event (Gpm_Event * event, void *d
  
  WInput *
  input_new (int y, int x, int color, int len, const char *def_text,
 -	   const char *histname)
 +	   const char *histname, INPUT_COMPLETE_FLAGS completion_flags)
  {
      WInput *in = g_new (WInput, 1);
      int initial_buffer_len;
@@@ -1672,7 -1672,7 +1673,7 @@@
      in->history_name = 0;
      if (histname) {
  	if (*histname) {
 -	    in->history_name = g_strdup (histname);
 +	    in->history_name = mhl_str_dup (histname);
  	    in->history = history_get (histname);
  	}
      }
@@@ -1689,7 -1689,9 +1690,7 @@@
      initial_buffer_len = 1 + max ((size_t) len, strlen (def_text));
      in->widget.options |= W_IS_INPUT;
      in->completions = NULL;
 -    in->completion_flags =
 -	INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_HOSTNAMES |
 -	INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES;
 +    in->completion_flags = completion_flags;
      in->current_max_len = initial_buffer_len;
      in->buffer = g_malloc (initial_buffer_len);
      in->color = color;
@@@ -1856,8 -1858,8 +1857,8 @@@ listbox_remove_list (WListbox *l
      
      while (l->count--) {
  	q = p->next;
- 	g_free (p->text);
- 	g_free (p);
+ 	mhl_mem_free (p->text);
+ 	mhl_mem_free (p);
  	p = q;
      }
      l->pos = l->count = 0;
@@@ -1898,8 -1900,8 +1899,8 @@@ listbox_remove_current (WListbox *l, in
  	l->list = l->top = l->current = 0;
      }
  
-     g_free (p->text);
-     g_free (p);
+     mhl_mem_free (p->text);
+     mhl_mem_free (p);
  }
  
  /* Makes *e the selected entry (sets current and pos) */
@@@ -2021,8 -2023,8 +2022,8 @@@ listbox_destroy (WListbox *l
  
      for (i = 0; i < l->count; i++){
  	n = p->next;
- 	g_free (p->text);
- 	g_free (p);
+ 	mhl_mem_free (p->text);
+ 	mhl_mem_free (p);
  	p = n;
      }
  }
@@@ -2234,7 -2236,7 +2235,7 @@@ listbox_add_item (WListbox *l, enum app
  	    return NULL;
  	    
      entry = g_new (WLEntry, 1);
 -    entry->text = g_strdup (text);
 +    entry->text = mhl_str_dup (text);
      entry->data = data;
      entry->hotkey = hotkey;
  
@@@ -2283,7 -2285,7 +2284,7 @@@ listbox_get_current (WListbox *l, char 
  }
  
  /* returns TRUE if a function has been called, FALSE otherwise. */
 -static gboolean
 +static bool
  buttonbar_call (WButtonBar *bb, int i)
  {
      switch (bb->labels[i].tag) {
@@@ -2337,7 -2339,7 +2338,7 @@@ buttonbar_callback (Widget *w, widget_m
  
      case WIDGET_DESTROY:
  	for (i = 0; i < 10; i++)
- 	    g_free (bb->labels[i].text);
+ 	    mhl_mem_free (bb->labels[i].text);
  	return MSG_HANDLED;
  
      default:
@@@ -2384,9 -2386,9 +2385,9 @@@ buttonbar_new (int visible
  static void
  set_label_text (WButtonBar * bb, int index, const char *text)
  {
-     g_free (bb->labels[index - 1].text);
+     mhl_mem_free (bb->labels[index - 1].text);
  
 -    bb->labels[index - 1].text = g_strdup (text);
 +    bb->labels[index - 1].text = mhl_str_dup (text);
  }
  
  /* Find ButtonBar widget in the dialog */
@@@ -2442,7 -2444,7 +2443,7 @@@ buttonbar_set_label (Dlg_head *h, int i
  }
  
  void
 -buttonbar_set_visible (WButtonBar *bb, gboolean visible)
 +buttonbar_set_visible (WButtonBar *bb, bool visible)
  {
      bb->visible = visible;
  }
@@@ -2483,7 -2485,7 +2484,7 @@@ groupbox_callback (Widget *w, widget_ms
  	return MSG_HANDLED;
  
      case WIDGET_DESTROY:
- 	g_free (g->title);
+ 	mhl_mem_free (g->title);
  	return MSG_HANDLED;
  
      default:
@@@ -2504,9 -2506,9 +2505,9 @@@ groupbox_new (int x, int y, int width, 
      /* Strip existing spaces, add one space before and after the title */
      if (title) {
  	char *t;
 -	t = g_strstrip (g_strdup (title));
 +	t = g_strstrip (mhl_str_dup (title));
  	g->title = g_strconcat (" ", t, " ", (char *) NULL);
- 	g_free (t);
+ 	mhl_mem_free (t);
      }
  
      return g;
diff --combined src/wtools.c
index cfc25aa,2d23666..0990669
--- a/src/wtools.c
+++ b/src/wtools.c
@@@ -29,7 -29,7 +29,8 @@@
  #include <stdio.h>
  #include <string.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "global.h"
  #include "tty.h"
@@@ -38,6 -38,7 +39,6 @@@
  #include "widget.h"
  #include "wtools.h"
  #include "key.h"		/* mi_getch() */
 -#include "complete.h"		/* INPUT_COMPLETE_CD */
  #include "background.h"		/* parent_call */
  
  
@@@ -88,7 -89,7 +89,7 @@@ int run_listbox (Listbox *l
      else
  	val = l->list->pos;
      destroy_dlg (l->dlg);
-     g_free (l);
+     mhl_mem_free (l);
      return val;
  }
  
@@@ -208,7 -209,7 +209,7 @@@ do_create_message (int flags, const cha
      query_dialog (title, p, flags, 0);
      d = last_query_dlg;
      init_dlg (d);
-     g_free (p);
+     mhl_mem_free (p);
  
      return d;
  }
@@@ -230,7 -231,7 +231,7 @@@ create_message (int flags, const char *
      va_end (args);
  
      d = do_create_message (flags, title, p);
-     g_free (p);
+     mhl_mem_free (p);
  
      return d;
  }
@@@ -260,7 -261,7 +261,7 @@@ bg_message (int dummy, int *flags, cha
      (void) dummy;
      title = g_strconcat (_("Background process:"), " ", title, (char *) NULL);
      fg_message (*flags, title, text);
-     g_free (title);
+     mhl_mem_free (title);
  }
  #endif				/* WITH_BACKGROUND */
  
@@@ -287,7 -288,7 +288,7 @@@ message (int flags, const char *title, 
  #endif				/* WITH_BACKGROUND */
  	fg_message (flags, title, p);
  
-     g_free (p);
+     mhl_mem_free (p);
  }
  
  
@@@ -362,7 -363,7 +363,7 @@@ quick_dialog_skip (QuickDialog *qd, in
  	case quick_input:
  	    input =
  		input_new (ypos, xpos, INPUT_COLOR, qw->hotkey_pos,
 -			   qw->text, qw->histname);
 +			   qw->text, qw->histname, INPUT_COMPLETE_DEFAULT);
  	    input->is_password = qw->value == 1;
  	    input->point = 0;
  	    if (qw->value & 2)
@@@ -407,14 -408,14 +408,14 @@@
  		    *qw->str_result =
  			tilde_expand (((WInput *) w)->buffer);
  		else
 -		    *qw->str_result = g_strdup (((WInput *) w)->buffer);
 +		    *qw->str_result = mhl_str_dup (((WInput *) w)->buffer);
  		break;
  	    }
  	}
      }
      return_val = dd->ret_value;
      destroy_dlg (dd);
-     g_free (widgets);
+     mhl_mem_free (widgets);
  
      return return_val;
  }
@@@ -500,7 -501,7 +501,7 @@@ fg_input_dialog_help (const char *heade
      Quick_input.title = header;
      Quick_input.help = help;
      Quick_input.i18n = 1; /* The dialog is already translated. */
 -    p_text = g_strstrip (g_strdup (text));
 +    p_text = g_strstrip (mhl_str_dup (text));
      quick_widgets[INPUT_INDEX + 1].text = p_text;
      quick_widgets[INPUT_INDEX].text = def_text;
  
@@@ -515,7 -516,7 +516,7 @@@
  
      Quick_input.widgets = quick_widgets;
      ret = quick_dialog (&Quick_input);
-     g_free (p_text);
+     mhl_mem_free (p_text);
  
      if (ret != B_CANCEL) {
  	return my_str;
@@@ -562,7 -563,7 +563,7 @@@ input_expand_dialog (const char *header
      result = input_dialog (header, text, history_name, def_text);
      if (result) {
  	expanded = tilde_expand (result);
- 	g_free (result);
+ 	mhl_mem_free (result);
  	return expanded;
      }
      return result;
diff --combined src/x11conn.c
index 09a135f,e9e9900..8505932
--- a/src/x11conn.c
+++ b/src/x11conn.c
@@@ -35,17 -35,16 +35,18 @@@ typedef int dummy;		/* C99 forbids empt
  #else
  
  #include <setjmp.h>
- 
  #include <X11/Xlib.h>
  
+ #include <mhl/memory.h>
+ 
  #include "../src/global.h"
  
  #ifdef HAVE_GMODULE
  #  include <gmodule.h>
  #endif
  
 +#include <mhl/types.h>
 +
  #include "x11conn.h"
  
  /*** file scope type declarations **************************************/
@@@ -78,15 -77,15 +79,15 @@@ static GModule *x11_module
  
  #endif
  
 -static gboolean handlers_installed = FALSE;
 +static bool handlers_installed = FALSE;
  
  /* This flag is set as soon as an X11 error is reported. Usually that
   * means that the DISPLAY is not available anymore. We do not try to
   * reconnect, as that would violate the X11 protocol. */
 -static gboolean lost_connection = FALSE;
 +static bool lost_connection = FALSE;
  
  static jmp_buf x11_exception; /* FIXME: get a better name */
 -static gboolean longjmp_allowed = FALSE;
 +static bool longjmp_allowed = FALSE;
  
  /*** file private functions ********************************************/
  
@@@ -118,7 -117,7 +119,7 @@@ static void install_error_handlers(void
      handlers_installed = TRUE;
  }
  
 -static gboolean x11_available(void)
 +static bool x11_available(void)
  {
  #ifdef HAVE_GMODULE
      gchar *x11_module_fname;
@@@ -134,7 -133,7 +135,7 @@@
      if (x11_module == NULL)
  	x11_module = g_module_open ("libX11.so.6", G_MODULE_BIND_LAZY);
  
-     g_free (x11_module_fname);
+     mhl_mem_free (x11_module_fname);
  
      if (x11_module == NULL)
  	return FALSE;
diff --combined vfs/cpio.c
index 0019b4b,1dd54d9..deccfd8
--- a/vfs/cpio.c
+++ b/vfs/cpio.c
@@@ -22,7 -22,7 +22,8 @@@
  
  #include <errno.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -146,7 -146,7 +147,7 @@@ static void cpio_free_archive(struct vf
  	super->u.arch.fd = -1;
      for (l = super->u.arch.deferred; l; l = lnext) {
  	lnext = l->next;
- 	g_free (l);
+ 	mhl_mem_free (l);
      }
      super->u.arch.deferred = NULL;
  }
@@@ -164,7 -164,7 +165,7 @@@ cpio_open_cpio_file (struct vfs_class *
  	return -1;
      }
  
 -    super->name = g_strdup (name);
 +    super->name = mhl_str_dup (name);
      super->u.arch.fd = -1;	/* for now */
      mc_stat (name, &(super->u.arch.st));
      super->u.arch.type = CPIO_UNKNOWN;
@@@ -177,10 -177,10 +178,10 @@@
  	s = g_strconcat (name, decompress_extension (type), (char *) NULL);
  	if ((fd = mc_open (s, O_RDONLY)) == -1) {
  	    message (D_ERROR, MSG_ERROR, _("Cannot open cpio archive\n%s"), s);
- 	    g_free (s);
+ 	    mhl_mem_free (s);
  	    return -1;
  	}
- 	g_free (s);
+ 	mhl_mem_free (s);
      }
  
      super->u.arch.fd = fd;
@@@ -293,7 -293,7 +294,7 @@@ static ssize_t cpio_read_bin_head(struc
      }
      name = g_malloc(u.buf.c_namesize);
      if((len = mc_read(super->u.arch.fd, name, u.buf.c_namesize)) < u.buf.c_namesize) {
- 	g_free(name);
+ 	mhl_mem_free(name);
  	return STATUS_EOF;
      }
      name[u.buf.c_namesize - 1] = '\0';
@@@ -301,7 -301,7 +302,7 @@@
      cpio_skip_padding(super);
  
      if(!strcmp("TRAILER!!!", name)) { /* We got to the last record */
- 	g_free(name);
+ 	mhl_mem_free(name);
  	return STATUS_TRAIL;
      }
  
@@@ -352,7 -352,7 +353,7 @@@ static ssize_t cpio_read_oldc_head(stru
      name = g_malloc(hd.c_namesize);
      if((len = mc_read(super->u.arch.fd, name, hd.c_namesize)) == -1 ||
         (unsigned long) len < hd.c_namesize) {
- 	g_free (name);
+ 	mhl_mem_free (name);
  	return STATUS_EOF;
      }
      name[hd.c_namesize - 1] = '\0';
@@@ -360,7 -360,7 +361,7 @@@
      cpio_skip_padding(super);
  
      if(!strcmp("TRAILER!!!", name)) { /* We got to the last record */
- 	g_free(name);
+ 	mhl_mem_free(name);
  	return STATUS_TRAIL;
      }
  
@@@ -417,7 -417,7 +418,7 @@@ static ssize_t cpio_read_crc_head(struc
      name = g_malloc(hd.c_namesize);
      if((len = mc_read (super->u.arch.fd, name, hd.c_namesize)) == -1 ||
         (unsigned long) len < hd.c_namesize) {
- 	g_free (name);
+ 	mhl_mem_free (name);
  	return STATUS_EOF;
      }
      name[hd.c_namesize - 1] = '\0';
@@@ -425,7 -425,7 +426,7 @@@
      cpio_skip_padding(super);
  
      if(!strcmp("TRAILER!!!", name)) { /* We got to the last record */
- 	g_free(name);
+ 	mhl_mem_free(name);
  	return STATUS_TRAIL;
      }
  
@@@ -548,7 -548,7 +549,7 @@@ cpio_create_entry (struct vfs_class *me
  	    if (mc_read (super->u.arch.fd, inode->linkname, st->st_size)
  		< st->st_size) {
  		inode->linkname[0] = 0;
- 		g_free (name);
+ 		mhl_mem_free (name);
  		return STATUS_EOF;
  	    }
  	    inode->linkname[st->st_size] = 0;	/* Linkname stored without terminating \0 !!! */
@@@ -560,7 -560,7 +561,7 @@@
  
      }				/* !entry */
  
-     g_free (name);
+     mhl_mem_free (name);
      return STATUS_OK;
  }
  
diff --combined vfs/direntry.c
index d85c1d8,dcb4f0b..e496166
--- a/vfs/direntry.c
+++ b/vfs/direntry.c
@@@ -28,7 -28,7 +28,8 @@@
  
  #include <errno.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -76,7 -76,7 +77,7 @@@ vfs_s_new_entry (struct vfs_class *me, 
      total_entries++;
  
      if (name)
 -	entry->name = g_strdup (name);
 +	entry->name = mhl_str_dup (name);
  
      entry->ino = inode;
      entry->ino->ent = entry;
@@@ -98,14 -98,14 +99,14 @@@ vfs_s_free_inode (struct vfs_class *me
  	}
  
  	CALL (free_inode) (me, ino);
- 	g_free (ino->linkname);
+ 	mhl_mem_free (ino->linkname);
  	if (ino->localname){
  	    unlink (ino->localname);
- 	    g_free(ino->localname);
+ 	    mhl_mem_free(ino->localname);
  	}
  	total_inodes--;
  	ino->super->ino_usage--;
- 	g_free(ino);
+ 	mhl_mem_free(ino);
      } else ino->st.st_nlink--;
  }
  
@@@ -118,7 -118,7 +119,7 @@@ vfs_s_free_entry (struct vfs_class *me
  	    ent->next->prevp = ent->prevp;
      }
  
-     g_free (ent->name);
+     mhl_mem_free (ent->name);
      ent->name = NULL;
  	
      if (ent->ino){
@@@ -128,7 -128,7 +129,7 @@@
      }
  
      total_entries--;
-     g_free(ent);
+     mhl_mem_free(ent);
  }
  
  void
@@@ -230,14 -230,14 +231,14 @@@ vfs_s_resolve_symlink (struct vfs_clas
  	if (fullpath) {
  	    fullname = g_strconcat (fullpath, "/", linkname, NULL);
  	    linkname = fullname;
- 	    g_free (fullpath);
+ 	    mhl_mem_free (fullpath);
  	}
      }
  
      target =
  	(MEDATA->find_entry) (me, entry->dir->super->root, linkname,
  			      follow - 1, 0);
-     g_free (fullname);
+     mhl_mem_free (fullname);
      return target;
  }
  
@@@ -251,7 -251,7 +252,7 @@@ vfs_s_find_entry_tree (struct vfs_clas
  {
      size_t pseg;
      struct vfs_s_entry *ent = NULL;
 -    char * const pathref = g_strdup (a_path);
 +    char * const pathref = mhl_str_dup (a_path);
      char *path = pathref;
  
      canonicalize_pathname (path);
@@@ -261,7 -261,7 +262,7 @@@
  	    path++;
  
  	if (!path[0]) {
- 	    g_free (pathref);
+ 	    mhl_mem_free (pathref);
  	    return ent;
  	}
  
@@@ -292,7 -292,7 +293,7 @@@
  	root = ent->ino;
      }
  cleanup:
-     g_free (pathref);
+     mhl_mem_free (pathref);
      return NULL;
  }
  
@@@ -321,7 -321,7 +322,7 @@@ vfs_s_find_entry_linear (struct vfs_cla
  			 const char *a_path, int follow, int flags)
  {
      struct vfs_s_entry *ent = NULL;
 -    char * const path = g_strdup (a_path);
 +    char * const path = mhl_str_dup (a_path);
      struct vfs_s_entry *retval = NULL;
  
      if (root->super->root != root)
@@@ -339,7 -339,7 +340,7 @@@
  	if (save)
  	    *save = PATH_SEP;
  	retval = vfs_s_find_entry_tree (me, ino, name, follow, flags);
- 	g_free (path);
+ 	mhl_mem_free (path);
  	return retval;
      }
  
@@@ -364,7 -364,7 +365,7 @@@
  	ent = vfs_s_new_entry (me, path, ino);
  	if ((MEDATA->dir_load) (me, ino, path) == -1) {
  	    vfs_s_free_entry (me, ent);
- 	    g_free (path);
+ 	    mhl_mem_free (path);
  	    return NULL;
  	}
  	vfs_s_insert_entry (me, root, ent);
@@@ -378,11 -378,11 +379,11 @@@
  
  #if 0
      if (!vfs_s_resolve_symlink (me, ent, follow)) {
-     	g_free (path);
+     	mhl_mem_free (path);
  	return NULL;
      }
  #endif
-     g_free (path);
+     mhl_mem_free (path);
      return ent;
  }
  
@@@ -449,8 -449,8 +450,8 @@@ vfs_s_free_super (struct vfs_class *me
      }
  
      CALL (free_archive) (me, super);
-     g_free (super->name);
-     g_free(super);
+     mhl_mem_free (super->name);
+     mhl_mem_free(super);
  }
  
  
@@@ -522,9 -522,9 +523,9 @@@ vfs_s_get_path (struct vfs_class *me, c
  {
      char *buf, *retval;
  
 -    buf = g_strdup (inname);
 -    retval = g_strdup (vfs_s_get_path_mangle (me, buf, archive, flags));
 +    buf = mhl_str_dup (inname);
 +    retval = mhl_str_dup (vfs_s_get_path_mangle (me, buf, archive, flags));
-     g_free (buf);
+     mhl_mem_free (buf);
      return retval;
  }
  
@@@ -546,13 -546,13 +547,13 @@@ vfs_s_fullpath (struct vfs_class *me, s
      if (!(MEDATA->flags & VFS_S_REMOTE)) {
  	/* archives */
  	char *newpath;
 -	char *path = g_strdup (ino->ent->name);
 +	char *path = mhl_str_dup (ino->ent->name);
  	while (1) {
  	    ino = ino->ent->dir;
  	    if (ino == ino->super->root)
  		break;
  	    newpath = g_strconcat (ino->ent->name, "/", path, (char *) NULL);
- 	    g_free (path);
+ 	    mhl_mem_free (path);
  	    path = newpath;
  	}
  	return path;
@@@ -560,7 -560,7 +561,7 @@@
  
      /* remote systems */
      if ((!ino->ent->dir) || (!ino->ent->dir->ent))
 -	return g_strdup (ino->ent->name);
 +	return mhl_str_dup (ino->ent->name);
  
      return g_strconcat (ino->ent->dir->ent->name, PATH_SEP_STR,
  			ino->ent->name, (char *) NULL);
@@@ -590,7 -590,7 +591,7 @@@ vfs_s_inode_from_path (struct vfs_clas
  			      flags & FL_FOLLOW ? LINK_FOLLOW :
  			      LINK_NO_FOLLOW,
  			      FL_DIR | (flags & ~FL_FOLLOW));
-     g_free (q);
+     mhl_mem_free (q);
      return ino;
  }
  
@@@ -651,7 -651,7 +652,7 @@@ vfs_s_closedir (void *data
      struct vfs_s_inode *dir = info->dir;
  
      vfs_s_free_inode (dir->super->me, dir);
-     g_free (data);
+     mhl_mem_free (data);
      return 0;
  }
  
@@@ -734,7 -734,7 +735,7 @@@ vfs_s_open (struct vfs_class *me, cons
  	return NULL;
      ino = vfs_s_find_inode (me, super, q, LINK_FOLLOW, FL_NONE);
      if (ino && ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
- 	g_free (q);
+ 	mhl_mem_free (q);
  	ERRNOR (EEXIST, NULL);
      }
      if (!ino) {
@@@ -745,7 -745,7 +746,7 @@@
  
  	/* If the filesystem is read-only, disable file creation */
  	if (!(flags & O_CREAT) || !(me->write)) {
- 	    g_free (q);
+ 	    mhl_mem_free (q);
  	    return NULL;
  	}
  
@@@ -759,14 -759,14 +760,14 @@@
  	vfs_s_insert_entry (me, dir, ent);
  	tmp_handle = vfs_mkstemps (&ino->localname, me->name, name);
  	if (tmp_handle == -1) {
- 	    g_free (q);
+ 	    mhl_mem_free (q);
  	    return NULL;
  	}
  	close (tmp_handle);
  	was_changed = 1;
      }
  
-     g_free (q);
+     mhl_mem_free (q);
  
      if (S_ISDIR (ino->st.st_mode))
  	ERRNOR (EISDIR, NULL);
@@@ -785,14 -785,14 +786,14 @@@
  	}
      } else if ((MEDATA->fh_open)
  	       && (MEDATA->fh_open (me, fh, flags, mode))) {
- 	g_free (fh);
+ 	mhl_mem_free (fh);
  	return NULL;
      }
  
      if (fh->ino->localname) {
  	fh->handle = open (fh->ino->localname, NO_LINEAR (flags), mode);
  	if (fh->handle == -1) {
- 	    g_free (fh);
+ 	    mhl_mem_free (fh);
  	    ERRNOR (errno, NULL);
  	}
      }
@@@ -901,7 -901,7 +902,7 @@@ vfs_s_close (void *fh
  	    res = -1;
   	else {
  	    res = MEDATA->file_store (me, fh, s, FH->ino->localname);
- 	    g_free (s);
+ 	    mhl_mem_free (s);
  	}
  	vfs_s_invalidate (me, FH_SUPER);
      }
@@@ -909,7 -909,7 +910,7 @@@
  	close (FH->handle);
  	
      vfs_s_free_inode (me, FH->ino);
-     g_free (fh);
+     mhl_mem_free (fh);
      return res;
  }
  
@@@ -995,7 -995,7 +996,7 @@@ vfs_s_retrieve_file (struct vfs_class *
      close (handle);
      unlink (ino->localname);
    error_4:
-     g_free (ino->localname);
+     mhl_mem_free (ino->localname);
      ino->localname = NULL;
      return -1;
  }
@@@ -1011,7 -1011,7 +1012,7 @@@ vfs_s_fill_names (struct vfs_class *me
      while (a){
  	name = g_strconcat ( a->name, "#", me->prefix, "/", /* a->current_dir->name, */ NULL);
  	(*func)(name);
- 	g_free (name);
+ 	mhl_mem_free (name);
  	a = a->next;
      }
  }
@@@ -1036,7 -1036,7 +1037,7 @@@ vfs_s_getlocalcopy (struct vfs_class *m
      if (!fh || !fh->ino || !fh->ino->localname)
  	return NULL;
  
 -    local = g_strdup (fh->ino->localname);
 +    local = mhl_str_dup (fh->ino->localname);
      vfs_s_close (fh);
      return local;
  }
@@@ -1095,7 -1095,7 +1096,7 @@@ vfs_s_getid (struct vfs_class *me, cons
  
      if (!(p = vfs_s_get_path (me, path, &archive, FL_NO_OPEN)))
  	return NULL;
-     g_free(p);
+     mhl_mem_free(p);
      return (vfsid) archive;    
  }
  
diff --combined vfs/extfs.c
index e4aef78,3f20ec9..0cb8bd7
--- a/vfs/extfs.c
+++ b/vfs/extfs.c
@@@ -36,7 -36,7 +36,8 @@@
  #endif
  #include <errno.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -125,7 -125,7 +126,7 @@@ extfs_fill_names (struct vfs_class *me
  	    g_strconcat (a->name ? a->name : "", "#",
  			 extfs_prefixes[a->fstype], (char *) NULL);
  	(*func) (name);
- 	g_free (name);
+ 	mhl_mem_free (name);
  	a = a->next;
      }
  }
@@@ -137,7 -137,7 +138,7 @@@ static void extfs_make_dots (struct ent
      struct inode *inode = ent->inode, *parent;
      
      parent = (parentry != NULL) ? parentry->inode : NULL;
 -    entry->name = g_strdup (".");
 +    entry->name = mhl_str_dup (".");
      entry->inode = inode;
      entry->dir = ent;
      inode->local_filename = NULL;
@@@ -145,7 -145,7 +146,7 @@@
      inode->nlink++;
      entry->next_in_dir = g_new (struct entry, 1);
      entry = entry->next_in_dir;
 -    entry->name = g_strdup ("..");
 +    entry->name = mhl_str_dup ("..");
      inode->last_in_subdir = entry;
      entry->next_in_dir = NULL;
      if (parent != NULL) {
@@@ -169,7 -169,7 +170,7 @@@ static struct entry *extfs_generate_ent
      parent = (parentry != NULL) ? parentry->inode : NULL;
      entry = g_new (struct entry, 1);
      
 -    entry->name = g_strdup (name);
 +    entry->name = mhl_str_dup (name);
      entry->next_in_dir = NULL;
      entry->dir = parentry;
      if (parent != NULL) {
@@@ -218,10 -218,10 +219,10 @@@ static void extfs_free_archive (struct 
          mc_stat (archive->local_name, &my);
          mc_ungetlocalcopy (archive->name, archive->local_name, 
              archive->local_stat.st_mtime != my.st_mtime);
-         g_free(archive->local_name);
+         mhl_mem_free(archive->local_name);
      }
-     g_free (archive->name);
-     g_free (archive);
+     mhl_mem_free (archive->name);
+     mhl_mem_free (archive);
  }
  
  static FILE *
@@@ -249,20 -249,20 +250,20 @@@ extfs_open_archive (int fstype, const c
  	tmp = name_quote (name, 0);
      }
  
 -    mc_extfsdir = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR);
 +    mc_extfsdir = mhl_str_dir_plus_file (mc_home, "extfs" PATH_SEP_STR);
      cmd =
  	g_strconcat (mc_extfsdir, extfs_prefixes[fstype], " list ",
  		     local_name ? local_name : tmp, (char *) NULL);
-     g_free (tmp);
-     g_free (mc_extfsdir);
+     mhl_mem_free (tmp);
+     mhl_mem_free (mc_extfsdir);
      open_error_pipe ();
      result = popen (cmd, "r");
-     g_free (cmd);
+     mhl_mem_free (cmd);
      if (result == NULL) {
  	close_error_pipe (D_ERROR, NULL);
  	if (local_name) {
  	    mc_ungetlocalcopy (name, local_name, 0);
- 	    g_free(local_name);
+ 	    mhl_mem_free(local_name);
  	}
  	return NULL;
      } 
@@@ -272,7 -272,7 +273,7 @@@
  
      current_archive = g_new (struct archive, 1);
      current_archive->fstype = fstype;
 -    current_archive->name = name ? g_strdup (name) : NULL;
 +    current_archive->name = name ? mhl_str_dup (name) : NULL;
      current_archive->local_name = local_name;
  
      if (local_name != NULL)
@@@ -355,13 -355,13 +356,13 @@@ extfs_read_archive (int fstype, const c
  				      0);
  		if (pent == NULL) {
  		    /* FIXME: Should clean everything one day */
- 		    g_free (buffer);
+ 		    mhl_mem_free (buffer);
  		    pclose (extfsd);
  		    close_error_pipe (D_ERROR, _("Inconsistent extfs archive"));
  		    return -1;
  		}
  		entry = g_new (struct entry, 1);
 -		entry->name = g_strdup (p);
 +		entry->name = mhl_str_dup (p);
  		entry->next_in_dir = NULL;
  		entry->dir = pent;
  		if (pent->inode->last_in_subdir) {
@@@ -374,7 -374,7 +375,7 @@@
  					  current_link_name, 0, 0);
  		    if (pent == NULL) {
  			/* FIXME: Should clean everything one day */
- 			g_free (buffer);
+ 			mhl_mem_free (buffer);
  			pclose (extfsd);
  			close_error_pipe (D_ERROR,
  					  _("Inconsistent extfs archive"));
@@@ -419,11 -419,11 +420,11 @@@
  		}
  	    }
  	  read_extfs_continue:
- 	    g_free (current_file_name);
- 	    g_free (current_link_name);
+ 	    mhl_mem_free (current_file_name);
+ 	    mhl_mem_free (current_link_name);
  	}
      }
-     g_free (buffer);
+     mhl_mem_free (buffer);
  
      /* Check if extfs 'list' returned 0 */
      if (pclose (extfsd) != 0) {
@@@ -493,12 -493,12 +494,12 @@@ static char 
  extfs_get_path (struct vfs_class *me, const char *inname, struct archive **archive,
  		int do_not_open)
  {
 -    char *buf = g_strdup (inname);
 +    char *buf = mhl_str_dup (inname);
      char *res = extfs_get_path_mangle (me, buf, archive, do_not_open);
      char *res2 = NULL;
      if (res)
 -	res2 = g_strdup (res);
 +	res2 = mhl_str_dup (res);
-     g_free (buf);
+     mhl_mem_free (buf);
      return res2;
  }
  
@@@ -522,7 -522,7 +523,7 @@@ static char *extfs_get_path_from_entry 
      }
  
      if (len == 0)
 -	return g_strdup ("");
 +	return mhl_str_dup ("");
      
      localpath = g_malloc (len);
      *localpath = '\0';
@@@ -532,7 -532,7 +533,7 @@@
  	    strcat (localpath, "/");
  	p = head;
  	head = head->next;
- 	g_free (p);
+ 	mhl_mem_free (p);
      }
      return (localpath);
  }
@@@ -567,7 -567,7 +568,7 @@@ extfs_resolve_symlinks_int (struct entr
      looping->entry = entry;
      looping->next = list;
      pent = extfs_find_entry_int (entry->dir, entry->inode->linkname, looping, 0, 0);
-     g_free (looping);
+     mhl_mem_free (looping);
      if (pent == NULL)
      	my_errno = ENOENT;
      return pent;
@@@ -620,22 -620,22 +621,22 @@@ extfs_cmd (const char *extfs_cmd, struc
  
      file = extfs_get_path_from_entry (entry);
      quoted_file = name_quote (file, 0);
-     g_free (file);
+     mhl_mem_free (file);
      archive_name = name_quote (extfs_get_archive_name (archive), 0);
      quoted_localname = name_quote (localname, 0);
  
 -    mc_extfsdir = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR);
 +    mc_extfsdir = mhl_str_dir_plus_file (mc_home, "extfs" PATH_SEP_STR);
      cmd = g_strconcat (mc_extfsdir, extfs_prefixes[archive->fstype],
  		       extfs_cmd, archive_name, " ", quoted_file, " ",
  		       quoted_localname, (char *) NULL);
-     g_free (quoted_file);
-     g_free (quoted_localname);
-     g_free (mc_extfsdir);
-     g_free (archive_name);
+     mhl_mem_free (quoted_file);
+     mhl_mem_free (quoted_localname);
+     mhl_mem_free (mc_extfsdir);
+     mhl_mem_free (archive_name);
  
      open_error_pipe ();
      retval = my_system (EXECUTE_AS_SHELL, shell, cmd);
-     g_free (cmd);
+     mhl_mem_free (cmd);
      close_error_pipe (D_ERROR, NULL);
      return retval;
  }
@@@ -650,17 -650,17 +651,17 @@@ extfs_run (struct vfs_class *me, const 
      if ((p = extfs_get_path (me, file, &archive, 0)) == NULL)
  	return;
      q = name_quote (p, 0);
-     g_free (p);
+     mhl_mem_free (p);
  
      archive_name = name_quote (extfs_get_archive_name (archive), 0);
 -    mc_extfsdir = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR);
 +    mc_extfsdir = mhl_str_dir_plus_file (mc_home, "extfs" PATH_SEP_STR);
      cmd = g_strconcat (mc_extfsdir, extfs_prefixes[archive->fstype],
  		       " run ", archive_name, " ", q, (char *) NULL);
-     g_free (mc_extfsdir);
-     g_free (archive_name);
-     g_free (q);
+     mhl_mem_free (mc_extfsdir);
+     mhl_mem_free (archive_name);
+     mhl_mem_free (q);
      shell_execute (cmd, 0);
-     g_free (cmd);
+     mhl_mem_free (cmd);
  }
  
  static void *
@@@ -682,7 -682,7 +683,7 @@@ extfs_open (struct vfs_class *me, cons
  	created = (entry != NULL);
      }
  
-     g_free (q);
+     mhl_mem_free (q);
      if (entry == NULL)
  	return NULL;
      if ((entry = extfs_resolve_symlinks (entry)) == NULL)
@@@ -765,7 -765,7 +766,7 @@@ extfs_close (void *data
      if (!file->archive->fd_usage)
  	vfs_stamp_create (&vfs_extfs_ops, file->archive);
  
-     g_free (data);
+     mhl_mem_free (data);
      if (errno_code)
  	ERRNOR (EIO, -1);
      return 0;
@@@ -881,7 -881,7 +882,7 @@@ static void * extfs_opendir (struct vfs
      if ((q = extfs_get_path (me, dirname, &archive, 0)) == NULL)
  	return NULL;
      entry = extfs_find_entry (archive->root_entry, q, 0, 0);
-     g_free (q);
+     mhl_mem_free (q);
      if (entry == NULL)
      	return NULL;
      if ((entry = extfs_resolve_symlinks (entry)) == NULL)
@@@ -913,7 -913,7 +914,7 @@@ static void * extfs_readdir(void *data
  
  static int extfs_closedir (void *data)
  {
-     g_free (data);
+     mhl_mem_free (data);
      return 0;
  }
  
@@@ -947,7 -947,7 +948,7 @@@ extfs_internal_stat (struct vfs_class *
      struct archive *archive;
      char *q;
      struct entry *entry;
 -    char *path2 = g_strdup (path);
 +    char *path2 = mhl_str_dup (path);
      int result = -1;
  
      if ((q = extfs_get_path_mangle (me, path2, &archive, 0)) == NULL)
@@@ -960,7 -960,7 +961,7 @@@
      extfs_stat_move (buf, entry->inode);
      result = 0;
  cleanup:
-     g_free (path2);
+     mhl_mem_free (path2);
      return result;
  }
  
@@@ -989,7 -989,7 +990,7 @@@ extfs_readlink (struct vfs_class *me, c
      char *q;
      size_t len;
      struct entry *entry;
 -    char *mpath = g_strdup (path);
 +    char *mpath = mhl_str_dup (path);
      int result = -1;
  
      if ((q = extfs_get_path_mangle (me, mpath, &archive, 0)) == NULL)
@@@ -1007,7 -1007,7 +1008,7 @@@
      /* readlink() does not append a NUL character to buf */
      memcpy (buf, entry->inode->linkname, result = len);
  cleanup:
-     g_free (mpath);
+     mhl_mem_free (mpath);
      return result;
  }
  
@@@ -1030,7 -1030,7 +1031,7 @@@ static ssize_t extfs_write (void *data
  static int extfs_unlink (struct vfs_class *me, const char *file)
  {
      struct archive *archive;
 -    char *q, *mpath = g_strdup (file);
 +    char *q, *mpath = mhl_str_dup (file);
      struct entry *entry;
      int result = -1;
  
@@@ -1052,14 -1052,14 +1053,14 @@@
      extfs_remove_entry (entry);
      result = 0;
  cleanup:
-     g_free (mpath);
+     mhl_mem_free (mpath);
      return result;
  }
  
  static int extfs_mkdir (struct vfs_class *me, const char *path, mode_t mode)
  {
      struct archive *archive;
 -    char *q, *mpath = g_strdup(path);
 +    char *q, *mpath = mhl_str_dup(path);
      struct entry *entry;
      int result = -1;
  
@@@ -1089,14 -1089,14 +1090,14 @@@
      }
      result = 0;
  cleanup:
-     g_free (mpath);
+     mhl_mem_free (mpath);
      return result;
  }
  
  static int extfs_rmdir (struct vfs_class *me, const char *path)
  {
      struct archive *archive;
 -    char *q, *mpath = g_strdup(path);
 +    char *q, *mpath = mhl_str_dup(path);
      struct entry *entry;
      int result = -1;
  
@@@ -1119,7 -1119,7 +1120,7 @@@
      extfs_remove_entry (entry);
      result = 0;
  cleanup:
-     g_free (mpath);
+     mhl_mem_free (mpath);
      return result;
  }
  
@@@ -1134,7 -1134,7 +1135,7 @@@ extfs_chdir (struct vfs_class *me, cons
      if ((q = extfs_get_path (me, path, &archive, 0)) == NULL)
  	return -1;
      entry = extfs_find_entry (archive->root_entry, q, 0, 0);
-     g_free (q);
+     mhl_mem_free (q);
      if (!entry)
  	return -1;
      entry = extfs_resolve_symlinks (entry);
@@@ -1159,7 -1159,7 +1160,7 @@@ extfs_getid (struct vfs_class *me, cons
  
      if (!(p = extfs_get_path (me, path, &archive, 1)))
  	return NULL;
-     g_free (p);
+     mhl_mem_free (p);
      return (vfsid) archive;
  }
  
@@@ -1201,12 -1201,12 +1202,12 @@@ static void extfs_remove_entry (struct 
              unlink (e->inode->local_filename);
              free (e->inode->local_filename);
          }
-         g_free (e->inode->linkname);
-         g_free (e->inode);
+         mhl_mem_free (e->inode->linkname);
+         mhl_mem_free (e->inode);
      }
  
-     g_free (e->name);
-     g_free (e);
+     mhl_mem_free (e->name);
+     mhl_mem_free (e);
  }
  
  static void extfs_free_entry (struct entry *e)
@@@ -1223,13 -1223,13 +1224,13 @@@
              unlink (e->inode->local_filename);
              free (e->inode->local_filename);
          }
-         g_free (e->inode->linkname);
-         g_free (e->inode);
+         mhl_mem_free (e->inode->linkname);
+         mhl_mem_free (e->inode);
      }
      if (e->next_in_dir != NULL)
          extfs_free_entry (e->next_in_dir);
-     g_free (e->name);
-     g_free (e);
+     mhl_mem_free (e->name);
+     mhl_mem_free (e);
  }
  
  static void extfs_free (vfsid id)
@@@ -1262,7 -1262,7 +1263,7 @@@ extfs_getlocalcopy (struct vfs_class *m
  	extfs_close ((void *) fp);
  	return NULL;
      }
 -    p = g_strdup (fp->entry->inode->local_filename);
 +    p = mhl_str_dup (fp->entry->inode->local_filename);
      fp->archive->fd_usage++;
      extfs_close ((void *) fp);
      return p;
@@@ -1298,7 -1298,7 +1299,7 @@@ static int extfs_init (struct vfs_clas
  
      (void) me;
  
 -    mc_extfsini = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR "extfs.ini");
 +    mc_extfsini = mhl_str_dir_plus_file (mc_home, "extfs" PATH_SEP_STR "extfs.ini");
      cfg = fopen (mc_extfsini, "r");
  
      /* We may not use vfs_die() message or message or similar,
@@@ -1306,7 -1306,7 +1307,7 @@@
       * appear on screen. */
      if (!cfg) {
  	fprintf (stderr, _("Warning: file %s not found\n"), mc_extfsini);
- 	g_free (mc_extfsini);
+ 	mhl_mem_free (mc_extfsini);
  	return 0;
      }
  
@@@ -1322,7 -1322,7 +1323,7 @@@
  	    fprintf(stderr, "Warning: You need to update your %s file.\n",
  		    mc_extfsini);
  	    fclose(cfg);
- 	    g_free (mc_extfsini);
+ 	    mhl_mem_free (mc_extfsini);
  	    return 0;
  	}
  	if (*key == '#' || *key == '\n')
@@@ -1339,10 -1339,10 +1340,10 @@@
  	if (!(*key))
  	    continue;
  
 -	extfs_prefixes [extfs_no++] = g_strdup (key);
 +	extfs_prefixes [extfs_no++] = mhl_str_dup (key);
      }
      fclose(cfg);
-     g_free (mc_extfsini);
+     mhl_mem_free (mc_extfsini);
      return 1;
  }
  
@@@ -1371,7 -1371,7 +1372,7 @@@ static void extfs_done (struct vfs_clas
      }
  
      for (i = 0; i < extfs_no; i++ )
- 	g_free (extfs_prefixes [i]);
+ 	mhl_mem_free (extfs_prefixes [i]);
      extfs_no = 0;
  }
  
diff --combined vfs/ftpfs.c
index d221395,e3b3653..2c09000
--- a/vfs/ftpfs.c
+++ b/vfs/ftpfs.c
@@@ -44,8 -44,8 +44,8 @@@ What to do with this
          int f = !strcmp( remote_path, "/~" );
  	if (f || !strncmp( remote_path, "/~/", 3 )) {
  	    char *s;
 -	    s = concat_dir_and_file( qhome (*bucket), remote_path +3-f );
 +	    s = mhl_str_dir_plus_file( qhome (*bucket), remote_path +3-f );
- 	    g_free (remote_path);
+ 	    mhl_mem_free (remote_path);
  	    remote_path = s;
  	}
      }
@@@ -56,6 -56,7 +56,7 @@@
  /* Namespace pollution: horrible */
  
  #include <config.h>
+ 
  #include <sys/types.h>          /* POSIX-required by sys/socket.h and netdb.h */
  #include <netdb.h>		/* struct hostent */
  #include <sys/socket.h>		/* AF_INET */
@@@ -69,7 -70,7 +70,8 @@@
  #include <errno.h>
  #include <ctype.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -174,7 -175,7 +176,7 @@@ static char 
  ftpfs_translate_path (struct vfs_class *me, struct vfs_s_super *super, const char *remote_path)
  {
      if (!SUP.remote_is_amiga)
 -	return g_strdup (remote_path);
 +	return mhl_str_dup (remote_path);
      else {
  	char *ret, *p;
  
@@@ -192,9 -193,9 +194,9 @@@
  	 * invalid.
  	 */
          if (*remote_path == '\0')
 -	    return g_strdup ("."); 
 +	    return mhl_str_dup ("."); 
  
 -	ret = g_strdup (remote_path);
 +	ret = mhl_str_dup (remote_path);
  
  	/* replace first occurance of ":/" with ":" */
  	if ((p = strchr (ret, ':')) && *(p + 1) == '/')
@@@ -235,7 -236,7 +237,7 @@@ ftpfs_split_url(char *path, char **host
  	if (use_netrc)
  	    ftpfs_netrc_lookup (*host, user, pass);
  	if (!*user)
 -	    *user = g_strdup ("anonymous");
 +	    *user = mhl_str_dup ("anonymous");
      }
  
      /* Look up password in netrc for known user */
@@@ -246,14 -247,14 +248,14 @@@
  
  	/* If user is different, remove password */
  	if (new_user && strcmp (*user, new_user)) {
- 	    g_free (*pass);
+ 	    mhl_mem_free (*pass);
  	    *pass = NULL;
  	}
  
- 	g_free (new_user);
+ 	mhl_mem_free (new_user);
      }
  
-     g_free (p);
+     mhl_mem_free (p);
  }
  
  /* Returns a reply code, check /usr/include/arpa/ftp.h for possible values */
@@@ -310,7 -311,7 +312,7 @@@ ftpfs_reconnect (struct vfs_class *me, 
  	    if (!cwdir)
  		return 1;
  	    sock = ftpfs_chdir_internal (me, super, cwdir);
- 	    g_free (cwdir);
+ 	    mhl_mem_free (cwdir);
  	    return sock == COMPLETE;
  	}
  	SUP.cwdir = cwdir;
@@@ -364,7 -365,7 +366,7 @@@ ftpfs_command (struct vfs_class *me, st
  	    }
  	    got_sigpipe = 1;
  	}
- 	g_free (cmdstr);
+ 	mhl_mem_free (cmdstr);
  	disable_interrupt_key ();
  	return TRANSIENT;
      }
@@@ -388,10 -389,10 +390,10 @@@
  	    }
  	}
  	retry = 0;
-         g_free (cmdstr);	
+         mhl_mem_free (cmdstr);	
  	return status;
      }
-     g_free (cmdstr);    
+     mhl_mem_free (cmdstr);    
      return COMPLETE;
  }
  
@@@ -403,10 -404,10 +405,10 @@@ ftpfs_free_archive (struct vfs_class *m
  	ftpfs_command(me, super, NONE, "QUIT");
  	close(SUP.sock);
      }
-     g_free (SUP.host);
-     g_free (SUP.user);
-     g_free (SUP.cwdir);
-     g_free (SUP.password);
+     mhl_mem_free (SUP.host);
+     mhl_mem_free (SUP.user);
+     mhl_mem_free (SUP.cwdir);
+     mhl_mem_free (SUP.password);
  }
  
  /* some defines only used by ftpfs_changetype */
@@@ -443,13 -444,13 +445,13 @@@ ftpfs_login_server (struct vfs_class *m
      SUP.isbinary = TYPE_UNKNOWN;
  
      if (SUP.password)		/* explicit password */
 -	op = g_strdup (SUP.password);
 +	op = mhl_str_dup (SUP.password);
      else if (netrcpass)		/* password from netrc */
 -	op = g_strdup (netrcpass);
 +	op = mhl_str_dup (netrcpass);
      else if (!strcmp (SUP.user, "anonymous") || !strcmp (SUP.user, "ftp")) {
  	if (!ftpfs_anonymous_passwd)	/* default anonymous password */
  	    ftpfs_init_passwd ();
 -	op = g_strdup (ftpfs_anonymous_passwd);
 +	op = mhl_str_dup (ftpfs_anonymous_passwd);
  	anon = 1;
      } else {			/* ask user */
  	char *p;
@@@ -457,10 -458,10 +459,10 @@@
  	p = g_strconcat (_(" FTP: Password required for "), SUP.user, " ",
  			 NULL);
  	op = vfs_get_password (p);
- 	g_free (p);
+ 	mhl_mem_free (p);
  	if (op == NULL)
  	    ERRNOR (EPERM, 0);
 -	SUP.password = g_strdup (op);
 +	SUP.password = mhl_str_dup (op);
      }
  
      if (!anon || MEDATA->logfile)
@@@ -477,7 -478,7 +479,7 @@@
  			 SUP.host[0] == '!' ? SUP.host + 1 : SUP.host,
  			 NULL);
      } else
 -	name = g_strdup (SUP.user);
 +	name = mhl_str_dup (SUP.user);
  
      if (ftpfs_get_reply
  	(me, SUP.sock, reply_string,
@@@ -503,13 -504,13 +505,13 @@@
  				     ("FTP: Account required for user %s"),
  				     SUP.user);
  		op = input_dialog (p, _("Account:"), MC_HISTORY_FTPFS_ACCOUNT, "");
- 		g_free (p);
+ 		mhl_mem_free (p);
  		if (op == NULL)
  		    ERRNOR (EPERM, 0);
  		print_vfs_message (_("ftpfs: sending user account"));
  		code =
  		    ftpfs_command (me, super, WAIT_REPLY, "ACCT %s", op);
- 		g_free (op);
+ 		mhl_mem_free (op);
  	    }
  	    if (code != COMPLETE)
  		break;
@@@ -518,7 -519,7 +520,7 @@@
  	case COMPLETE:
  	    print_vfs_message (_("ftpfs: logged in"));
  	    wipe_password (pass);
- 	    g_free (name);
+ 	    mhl_mem_free (name);
  	    return 1;
  
  	default:
@@@ -534,7 -535,7 +536,7 @@@
  	     SUP.user);
    login_fail:
      wipe_password (pass);
-     g_free (name);
+     mhl_mem_free (name);
      ERRNOR (EPERM, 0);
  }
  
@@@ -557,7 -558,7 +559,7 @@@ ftpfs_load_no_proxy_list (void
      if (mc_file)
  	return;
  
 -    mc_file = concat_dir_and_file (mc_home, "mc.no_proxy");
 +    mc_file = mhl_str_dir_plus_file (mc_home, "mc.no_proxy");
      if (exist_file (mc_file) &&
  	(npf = fopen (mc_file, "r"))) {
  	while (fgets (s, sizeof (s), npf)) {
@@@ -573,7 -574,7 +575,7 @@@
  	    *p = '\0';
  	    
  	    np = g_new (struct no_proxy_entry, 1);
 -	    np->domain = g_strdup (s);
 +	    np->domain = mhl_str_dup (s);
  	    np->next   = NULL;
  	    if (no_proxy)
  		current->next = np;
@@@ -584,7 -585,7 +586,7 @@@
  
  	fclose (npf);
      }
-     g_free (mc_file);
+     mhl_mem_free (mc_file);
  }
  
  /* Return 1 if FTP proxy should be used for this host, 0 otherwise */
@@@ -636,8 -637,8 +638,8 @@@ ftpfs_get_proxy_host_and_port (const ch
      dir =
  	vfs_split_url (proxy, host, &user, port, 0, FTP_COMMAND_PORT,
  		       URL_ALLOW_ANON);
-     g_free (user);
-     g_free (dir);
+     mhl_mem_free (user);
+     mhl_mem_free (dir);
  }
  
  static int
@@@ -680,7 -681,7 +682,7 @@@ ftpfs_open_socket (struct vfs_class *me
  	    print_vfs_message (_("ftpfs: Invalid host address."));
  	    ftpfs_errno = EINVAL;
  	    if (free_host)
- 		g_free (host);
+ 		mhl_mem_free (host);
  	    return -1;
  	}
  	server_address.sin_family = hp->h_addrtype;
@@@ -696,13 -697,13 +698,13 @@@
  	disable_interrupt_key();
  	ftpfs_errno = errno;
          if (free_host)
- 	    g_free (host);
+ 	    mhl_mem_free (host);
  	return -1;
      }
      
      print_vfs_message (_("ftpfs: making connection to %s"), host);
      if (free_host)
- 	g_free (host);
+ 	mhl_mem_free (host);
  
      if (connect (my_socket, (struct sockaddr *) &server_address,
  	     sizeof (server_address)) < 0){
@@@ -766,7 -767,7 +768,7 @@@ ftpfs_open_archive_int (struct vfs_clas
      
      SUP.cwdir = ftpfs_get_current_directory (me, super);
      if (!SUP.cwdir)
 -        SUP.cwdir = g_strdup (PATH_SEP_STR);
 +        SUP.cwdir = mhl_str_dup (PATH_SEP_STR);
      return 0;
  }
  
@@@ -793,7 -794,7 +795,7 @@@ ftpfs_open_archive (struct vfs_class *m
      SUP.strict = ftpfs_use_unix_list_options ? RFC_AUTODETECT : RFC_STRICT;
      SUP.isbinary = TYPE_UNKNOWN;
      SUP.remote_is_amiga = 0;
 -    super->name = g_strdup ("/");
 +    super->name = mhl_str_dup ("/");
      super->root =
  	vfs_s_new_inode (me, super,
  			 vfs_s_default_stat (me, S_IFDIR | 0755));
@@@ -817,8 -818,8 +819,8 @@@ ftpfs_archive_same (struct vfs_class *m
      port = ((strcmp (host, SUP.host) == 0)
  	    && (strcmp (user, SUP.user) == 0) && (port == SUP.port));
  
-     g_free (host);
-     g_free (user);
+     mhl_mem_free (host);
+     mhl_mem_free (user);
  
      return port;
  }
@@@ -844,7 -845,7 +846,7 @@@ ftpfs_get_current_directory (struct vfs
  		            *bufq = 0;
  		        }
  			if (*bufp == '/')
 -			    return g_strdup (bufp);
 +			    return mhl_str_dup (bufp);
  			else {
  			    /* If the remote server is an Amiga a leading slash
  			       might be missing. MC needs it because it is used
@@@ -969,7 -970,7 +971,7 @@@ ftpfs_open_data_connection (struct vfs_
  	j = ftpfs_command (me, super, WAIT_REPLY, "%s /%s", cmd, 
  	    /* WarFtpD can't STORE //filename */
  	    (*remote_path == '/') ? remote_path + 1 : remote_path);
- 	g_free (remote_path);
+ 	mhl_mem_free (remote_path);
      } else
      	j = ftpfs_command (me, super, WAIT_REPLY, "%s", cmd);
      if (j != PRELIM)
@@@ -1155,7 -1156,7 +1157,7 @@@ resolve_symlink_with_ls_options(struct 
  vfs_die("This code should be commented out\n");
  	    if (vfs_parse_ls_lga (buffer, &s, &filename, NULL)) {
  		int r = strcmp(fe->name, filename);
- 		g_free(filename);
+ 		mhl_mem_free(filename);
  		if (r == 0) {
                      if (S_ISLNK (s.st_mode)) {
                          /* This server doesn't understand LIST -lLa */
@@@ -1232,11 -1233,11 +1234,11 @@@ ftpfs_dir_load (struct vfs_class *me, s
  	    ftpfs_open_data_connection (me, super, "LIST -la", 0, TYPE_ASCII, 0);
      else {
  	/* Trailing "/." is necessary if remote_path is a symlink */
 -	char *path = concat_dir_and_file (remote_path, ".");
 +	char *path = mhl_str_dir_plus_file (remote_path, ".");
  	sock =
  	    ftpfs_open_data_connection (me, super, "LIST -la", path, TYPE_ASCII,
  				  0);
- 	g_free (path);
+ 	mhl_mem_free (path);
      }
  
      if (sock == -1)
@@@ -1409,7 -1410,7 +1411,7 @@@ ftpfs_linear_start (struct vfs_class *m
      if (!name)
  	return 0;
      FH_SOCK = ftpfs_open_data_connection(me, FH_SUPER, "RETR", name, TYPE_BINARY, offset);
-     g_free (name);
+     mhl_mem_free (name);
      if (FH_SOCK == -1)
  	ERRNOR (EACCES, 0);
      fh->linear = LS_LINEAR_OPEN;
@@@ -1479,29 -1480,29 +1481,29 @@@ static in
  ftpfs_send_command(struct vfs_class *me, const char *filename, const char *cmd, int flags)
  {
      const char *rpath;
 -    char *p, *mpath = g_strdup(filename);
 +    char *p, *mpath = mhl_str_dup(filename);
      struct vfs_s_super *super;
      int r;
      int flush_directory_cache = (flags & OPT_FLUSH);
  
      if (!(rpath = vfs_s_get_path_mangle(me, mpath, &super, 0))) {
-     	g_free(mpath);
+     	mhl_mem_free(mpath);
  	return -1;
      }
      p = ftpfs_translate_path (me, super, rpath);
      r = ftpfs_command (me, super, WAIT_REPLY, cmd, p);
-     g_free (p);
+     mhl_mem_free (p);
      vfs_stamp_create (&vfs_ftpfs_ops, super);
      if (flags & OPT_IGNORE_ERROR)
  	r = COMPLETE;
      if (r != COMPLETE) {
          me->verrno = EPERM;
-         g_free (mpath);
+         mhl_mem_free (mpath);
          return -1;
      }
      if (flush_directory_cache)
  	vfs_s_invalidate(me, super);
-     g_free(mpath);
+     mhl_mem_free(mpath);
      return 0;
  }
  
@@@ -1521,14 -1522,14 +1523,14 @@@ ftpfs_init_passwd(void
       * - We don't want to let ftp sites to discriminate by the user,
       *   host or country.
       */
 -    ftpfs_anonymous_passwd = g_strdup ("anonymous@");
 +    ftpfs_anonymous_passwd = mhl_str_dup ("anonymous@");
  }
  
  static int ftpfs_chmod (struct vfs_class *me, const char *path, int mode)
  {
      char buf[BUF_SMALL];
  
 -    g_snprintf(buf, sizeof(buf), "SITE CHMOD %4.4o /%%s", mode & 07777);
 +    snprintf(buf, sizeof(buf), "SITE CHMOD %4.4o /%%s", mode & 07777);
      return ftpfs_send_command(me, path, buf, OPT_FLUSH);
  }
  
@@@ -1577,13 -1578,13 +1579,13 @@@ ftpfs_chdir_internal (struct vfs_class 
  
      p = ftpfs_translate_path (me, super, remote_path);
      r = ftpfs_command (me, super, WAIT_REPLY, "CWD /%s", p);
-     g_free (p);
+     mhl_mem_free (p);
  
      if (r != COMPLETE) {
  	ftpfs_errno = EIO;
      } else {
- 	g_free(SUP.cwdir);
+ 	mhl_mem_free(SUP.cwdir);
 -	SUP.cwdir = g_strdup (remote_path);
 +	SUP.cwdir = mhl_str_dup (remote_path);
  	SUP.cwd_deferred = 0;
      }
      return r;
@@@ -1645,7 -1646,7 +1647,7 @@@ ftpfs_fh_open (struct vfs_class *me, st
  	    ftpfs_open_data_connection (me, fh->ino->super,
  					(flags & O_APPEND) ? "APPE" :
  					"STOR", name, TYPE_BINARY, 0);
- 	g_free (name);
+ 	mhl_mem_free (name);
  
  	if (fh->handle < 0)
  	    return -1;
@@@ -1657,7 -1658,7 +1659,7 @@@
  
  	if (fh->ino->localname) {
  	    unlink (fh->ino->localname);
- 	    g_free (fh->ino->localname);
+ 	    mhl_mem_free (fh->ino->localname);
  	    fh->ino->localname = NULL;
  	}
  	return 0;
@@@ -1696,12 -1697,12 +1698,12 @@@ ftpfs_done (struct vfs_class *me
  
      while (no_proxy) {
  	np = no_proxy->next;
- 	g_free (no_proxy->domain);
- 	g_free (no_proxy);
+ 	mhl_mem_free (no_proxy->domain);
+ 	mhl_mem_free (no_proxy);
  	no_proxy = np;	
      }
-     g_free (ftpfs_anonymous_passwd);
-     g_free (ftpfs_proxy_host);
+     mhl_mem_free (ftpfs_anonymous_passwd);
+     mhl_mem_free (ftpfs_proxy_host);
  }
  
  static void
@@@ -1713,7 -1714,7 +1715,7 @@@ ftpfs_fill_names (struct vfs_class *me
      while (super){
  	name = g_strconcat ("/#ftp:", SUP.user, "@", SUP.host, "/", SUP.cwdir, (char *) NULL);
  	(*func)(name);
- 	g_free (name);
+ 	mhl_mem_free (name);
  	super = super->next;
      }
  }
@@@ -1880,18 -1881,18 +1882,18 @@@ static int ftpfs_netrc_lookup (const ch
      for (rupp = rup_cache; rupp != NULL; rupp = rupp->next) {
  	if (!strcmp (host, rupp->host)) {
  	    if (rupp->login)
 -		*login = g_strdup (rupp->login);
 +		*login = mhl_str_dup (rupp->login);
  	    if (pass && rupp->pass)
 -		*pass = g_strdup (rupp->pass);
 +		*pass = mhl_str_dup (rupp->pass);
  	    return 0;
  	}
      }
  
      /* Load current .netrc */
 -    netrcname = concat_dir_and_file (home_dir, ".netrc");
 +    netrcname = mhl_str_dir_plus_file (home_dir, ".netrc");
      netrcp = netrc = load_file (netrcname);
      if (netrc == NULL) {
- 	g_free (netrcname);
+ 	mhl_mem_free (netrcname);
  	return 0;
      }
  
@@@ -1923,7 -1924,7 +1925,7 @@@
  	    }
  
  	    /* We have login name now */
 -	    *login = g_strdup (buffer);
 +	    *login = mhl_str_dup (buffer);
  	    break;
  
  	case NETRC_PASSWORD:
@@@ -1942,7 -1943,7 +1944,7 @@@
  
  	    /* Remember password.  pass may be NULL, so use tmp_pass */
  	    if (tmp_pass == NULL)
 -		tmp_pass = g_strdup (buffer);
 +		tmp_pass = mhl_str_dup (buffer);
  	    break;
  
  	case NETRC_ACCOUNT:
@@@ -1966,18 -1967,18 +1968,18 @@@
  	    break;
      }
  
-     g_free (netrc);
-     g_free (netrcname);
+     mhl_mem_free (netrc);
+     mhl_mem_free (netrcname);
  
      rupp = g_new (struct rupcache, 1);
 -    rupp->host = g_strdup (host);
 +    rupp->host = mhl_str_dup (host);
      rupp->login = rupp->pass = 0;
  
      if (*login != NULL) {
 -	rupp->login = g_strdup (*login);
 +	rupp->login = mhl_str_dup (*login);
      }
      if (tmp_pass != NULL)
 -	rupp->pass = g_strdup (tmp_pass);
 +	rupp->pass = mhl_str_dup (tmp_pass);
      rupp->next = rup_cache;
      rup_cache = rupp;
  
diff --combined vfs/gc.c
index 8da8946,426532f..70d0e65
--- a/vfs/gc.c
+++ b/vfs/gc.c
@@@ -31,7 -31,7 +31,8 @@@
  #include <signal.h>
  #include <ctype.h>		/* is_digit() */
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -109,7 -109,7 +110,7 @@@ vfs_rmstamp (struct vfs_class *v, vfsi
  	    } else {
  		st1->next = stamp->next;
  	    }
- 	    g_free (stamp);
+ 	    mhl_mem_free (stamp);
  
  	    return;
  	}
@@@ -124,11 -124,11 +125,11 @@@ vfs_getid (struct vfs_class *vclass, co
      vfsid id = NULL;
  
      /* append slash if needed */
 -    dir1 = concat_dir_and_file (dir, "");
 +    dir1 = mhl_str_dir_plus_file (dir, "");
      if (vclass->getid)
  	id = (*vclass->getid) (vclass, dir1);
  
-     g_free (dir1);
+     mhl_mem_free (dir1);
      return id;
  }
  
@@@ -297,7 -297,7 +298,7 @@@ vfs_gc_done (void
  	if (stamp->v->free)
  	    (*stamp->v->free) (stamp->id);
  	st = stamp->next;
- 	g_free (stamp);
+ 	mhl_mem_free (stamp);
  	stamp = st;
      }
  
diff --combined vfs/local.c
index 29ff36b,f40f603..96ba885
--- a/vfs/local.c
+++ b/vfs/local.c
@@@ -5,7 -5,7 +5,8 @@@
  #include <stdio.h>
  #include <string.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -69,7 -69,7 +70,7 @@@ local_close (void *data
  	return -1;
      
      fd =  *(int *) data;
-     g_free (data);
+     mhl_mem_free (data);
      return close (fd);
  }
  
@@@ -110,7 -110,7 +111,7 @@@ local_closedir (void *data
      int i;
  
      i = closedir (* (DIR **) data);
-     g_free (data);
+     mhl_mem_free (data);
      return i;
  }
  
@@@ -272,7 -272,7 +273,7 @@@ local_getlocalcopy (struct vfs_class *m
  {
      (void) me;
  
 -    return g_strdup (path);
 +    return mhl_str_dup (path);
  }
  
  static int
diff --combined vfs/mcfs.c
index dde1b45,b96862c..293e59d
--- a/vfs/mcfs.c
+++ b/vfs/mcfs.c
@@@ -49,8 -49,6 +49,8 @@@
  #endif
  #endif
  
 +#include <mhl/string.h>
 +
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
  #include "../src/wtools.h"	/* message() */
@@@ -114,7 -112,7 +114,7 @@@ mcfs_fill_names (struct vfs_class *me, 
  	name = g_strconcat ("/#mc:", mcfs_connections[i].user,
  			    "@", mcfs_connections[i].host, (char *) NULL);
  	(*func) (name);
- 	g_free (name);
+ 	mhl_mem_free (name);
      }
  }
  
@@@ -161,7 -159,7 +161,7 @@@ mcfs_login_server (int my_socket, char 
  	    }
  	}
  	if (netrcpass != NULL)
 -	    pass = g_strdup (netrcpass);
 +	    pass = mhl_str_dup (netrcpass);
  	else
  	    pass = vfs_get_password (_(" MCFS Password required "));
  	if (!pass) {
@@@ -343,8 -341,8 +343,8 @@@ mcfs_open_link (char *host, char *user
  
      bucket = mcfs_get_free_bucket ();
      mcfs_open_connections++;
 -    bucket->host = g_strdup (host);
 -    bucket->user = g_strdup (user);
 +    bucket->host = mhl_str_dup (host);
 +    bucket->user = mhl_str_dup (user);
      bucket->home = 0;
      bucket->port = *port;
      bucket->sock = sock;
@@@ -392,11 -390,11 +392,11 @@@ mcfs_get_path (mcfs_connection **mc, co
      if ((remote_path =
  	 mcfs_get_host_and_username (path, &host, &user, &port, &pass)))
  	if (!(*mc = mcfs_open_link (host, user, &port, pass))) {
- 	    g_free (remote_path);
+ 	    mhl_mem_free (remote_path);
  	    remote_path = NULL;
  	}
-     g_free (host);
-     g_free (user);
+     mhl_mem_free (host);
+     mhl_mem_free (user);
      if (pass)
  	wipe_password (pass);
  
@@@ -408,9 -406,9 +408,9 @@@
  	int f = !strcmp (remote_path, "/~");
  	if (f || !strncmp (remote_path, "/~/", 3)) {
  	    char *s;
 -	    s = concat_dir_and_file (mcfs_gethome (*mc),
 +	    s = mhl_str_dir_plus_file (mcfs_gethome (*mc),
  				     remote_path + 3 - f);
- 	    g_free (remote_path);
+ 	    mhl_mem_free (remote_path);
  	    remote_path = s;
  	}
      }
@@@ -444,14 -442,14 +444,14 @@@ mcfs_rpc_two_paths (int command, const 
  	return -1;
  
      if ((r2 = mcfs_get_path (&mc, s2)) == 0) {
- 	g_free (r1);
+ 	mhl_mem_free (r1);
  	return -1;
      }
  
      rpc_send (mc->sock,
  	      RPC_INT, command, RPC_STRING, r1, RPC_STRING, r2, RPC_END);
-     g_free (r1);
-     g_free (r2);
+     mhl_mem_free (r1);
+     mhl_mem_free (r2);
      return mcfs_handle_simple_error (mc->sock, 0);
  }
  
@@@ -467,7 -465,7 +467,7 @@@ mcfs_rpc_path (int command, const char 
      rpc_send (mc->sock,
  	      RPC_INT, command, RPC_STRING, remote_file, RPC_END);
  
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
      return mcfs_handle_simple_error (mc->sock, 0);
  }
  
@@@ -484,7 -482,7 +484,7 @@@ mcfs_rpc_path_int (int command, const c
  	      RPC_INT, command,
  	      RPC_STRING, remote_file, RPC_INT, data, RPC_END);
  
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
      return mcfs_handle_simple_error (mc->sock, 0);
  }
  
@@@ -501,7 -499,7 +501,7 @@@ mcfs_rpc_path_int_int (int command, con
  	      RPC_INT, command,
  	      RPC_STRING, remote_file, RPC_INT, n1, RPC_INT, n2, RPC_END);
  
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
      return mcfs_handle_simple_error (mc->sock, 0);
  }
  
@@@ -511,13 -509,13 +511,13 @@@ mcfs_gethome (mcfs_connection *mc
      char *buffer;
  
      if (mc->home)
 -	return g_strdup (mc->home);
 +	return mhl_str_dup (mc->home);
      else {
  	rpc_send (mc->sock, RPC_INT, MC_GETHOME, RPC_END);
  	if (0 == rpc_get (mc->sock, RPC_STRING, &buffer, RPC_END))
 -	    return g_strdup (PATH_SEP_STR);
 +	    return mhl_str_dup (PATH_SEP_STR);
  	mc->home = buffer;
 -	return g_strdup (buffer);
 +	return mhl_str_dup (buffer);
      }
  }
  
@@@ -537,7 -535,7 +537,7 @@@ mcfs_open (struct vfs_class *me, const 
  
      rpc_send (mc->sock, RPC_INT, MC_OPEN, RPC_STRING, remote_file, RPC_INT,
  	      flags, RPC_INT, mode, RPC_END);
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
  
      if (0 ==
  	rpc_get (mc->sock, RPC_INT, &result, RPC_INT, &error_num, RPC_END))
@@@ -619,7 -617,7 +619,7 @@@ mcfs_close (void *data
  
      mcfs_is_error (result, error);
  
-     g_free (data);
+     mhl_mem_free (data);
      return result;
  }
  
@@@ -661,7 -659,7 +661,7 @@@ mcfs_opendir (struct vfs_class *me, con
  
      rpc_send (mc->sock, RPC_INT, MC_OPENDIR, RPC_STRING, remote_dir,
  	      RPC_END);
-     g_free (remote_dir);
+     mhl_mem_free (remote_dir);
  
      if (0 ==
  	rpc_get (mc->sock, RPC_INT, &result, RPC_INT, &error_num, RPC_END))
@@@ -744,8 -742,8 +744,8 @@@ mcfs_free_dir (dir_entry *de
      if (!de)
  	return;
      mcfs_free_dir (de->next);
-     g_free (de->text);
-     g_free (de);
+     mhl_mem_free (de->text);
+     mhl_mem_free (de);
  }
  
  static union vfs_dirent mcfs_readdir_data;
@@@ -795,10 -793,10 +795,10 @@@ mcfs_closedir (void *info
      for (p = mcfs_info->entries; p;) {
  	q = p;
  	p = p->next;
- 	g_free (q->text);
- 	g_free (q);
+ 	mhl_mem_free (q->text);
+ 	mhl_mem_free (q);
      }
-     g_free (info);
+     mhl_mem_free (info);
      return 0;
  }
  
@@@ -826,7 -824,7 +826,7 @@@ mcfs_get_time (mcfs_connection *mc
  
  	rpc_get (sock, RPC_STRING, &buf, RPC_END);
  	sscanf (buf, "%lx", &tm);
- 	g_free (buf);
+ 	mhl_mem_free (buf);
  
  	return (time_t) tm;
      }
@@@ -879,7 -877,7 +879,7 @@@ mcfs_stat_cmd (int cmd, const char *pat
  	return -1;
  
      rpc_send (mc->sock, RPC_INT, cmd, RPC_STRING, remote_file, RPC_END);
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
      if (!rpc_get (mc->sock, RPC_INT, &status, RPC_INT, &error, RPC_END))
  	return mcfs_set_error (-1, errno);
  
@@@ -977,8 -975,8 +977,8 @@@ mcfs_utime (struct vfs_class *me, cons
  	atime = (long) times->actime;
  	mtime = (long) times->modtime;
  
 -	g_snprintf (abuf, sizeof (abuf), "%lx", atime);
 -	g_snprintf (mbuf, sizeof (mbuf), "%lx", mtime);
 +	snprintf (abuf, sizeof (abuf), "%lx", atime);
 +	snprintf (mbuf, sizeof (mbuf), "%lx", mtime);
  
  	rpc_send (mc->sock, RPC_INT, MC_UTIME,
  		  RPC_STRING, file,
@@@ -986,7 -984,7 +986,7 @@@
  	status = mcfs_handle_simple_error (mc->sock, 0);
  
      }
-     g_free (file);
+     mhl_mem_free (file);
      return (status);
  }
  
@@@ -1005,7 -1003,7 +1005,7 @@@ mcfs_readlink (struct vfs_class *me, co
  
      rpc_send (mc->sock, RPC_INT, MC_READLINK, RPC_STRING, remote_file,
  	      RPC_END);
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
      if (!rpc_get (mc->sock, RPC_INT, &status, RPC_INT, &error, RPC_END))
  	return mcfs_set_error (-1, EIO);
  
@@@ -1020,7 -1018,7 +1020,7 @@@
         size = len;
      /* readlink() does not append a NUL character to buf */
      memcpy (buf, stat_str, size);
-     g_free (stat_str);
+     mhl_mem_free (stat_str);
      return size;
  }
  
@@@ -1062,7 -1060,7 +1062,7 @@@ mcfs_chdir (struct vfs_class *me, cons
  
      rpc_send (mc->sock, RPC_INT, MC_CHDIR, RPC_STRING, remote_dir,
  	      RPC_END);
-     g_free (remote_dir);
+     mhl_mem_free (remote_dir);
      if (!rpc_get (mc->sock, RPC_INT, &status, RPC_INT, &error, RPC_END))
  	return mcfs_set_error (-1, EIO);
  
@@@ -1138,8 -1136,8 +1138,8 @@@ mcfs_forget (const char *path
      if ((p =
  	 mcfs_get_host_and_username (path, &host, &user, &port,
  				     &pass)) == 0) {
- 	g_free (host);
- 	g_free (user);
+ 	mhl_mem_free (host);
+ 	mhl_mem_free (user);
  	if (pass)
  	    wipe_password (pass);
  	return;
@@@ -1157,9 -1155,9 +1157,9 @@@
  		mcfs_open_tcp_link (host, user, &port, pass, &vers);
  	}
      }
-     g_free (p);
-     g_free (host);
-     g_free (user);
+     mhl_mem_free (p);
+     mhl_mem_free (host);
+     mhl_mem_free (user);
      if (pass)
  	wipe_password (pass);
  }
@@@ -1215,9 -1213,9 +1215,9 @@@ init_mcfs (void
  static void
  mcfs_free_bucket (int bucket)
  {
-     g_free (mcfs_connections[bucket].host);
-     g_free (mcfs_connections[bucket].user);
-     g_free (mcfs_connections[bucket].home);
+     mhl_mem_free (mcfs_connections[bucket].host);
+     mhl_mem_free (mcfs_connections[bucket].user);
+     mhl_mem_free (mcfs_connections[bucket].home);
  
      /* Set all the fields to zero */
      mcfs_connections[bucket].host =
diff --combined vfs/sfs.c
index a8ae3ba,b2dd6fe..705de5d
--- a/vfs/sfs.c
+++ b/vfs/sfs.c
@@@ -34,7 -34,7 +34,8 @@@
  #include <stdio.h>
  #include <string.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -76,13 -76,13 +77,13 @@@ sfs_vfmake (struct vfs_class *me, cons
      char *pname;	/* name of parent archive */
      char *pqname;	/* name of parent archive, quoted */
  
 -    pname = g_strdup (name);
 +    pname = mhl_str_dup (name);
      vfs_split (pname, &inpath, &op);
      if ((w = (*me->which) (me, op)) == -1)
  	vfs_die ("This cannot happen... Hopefully.\n");
  
      if (!(sfs_flags[w] & F_1) && strcmp (pname, "/")) {
- 	g_free (pname);
+ 	mhl_mem_free (pname);
  	return -1;
      }
  
@@@ -90,19 -90,19 +91,19 @@@
      if (!(sfs_flags[w] & F_NOLOCALCOPY)) {
  	s = mc_getlocalcopy (pname);
  	if (!s) {
- 	    g_free (pname);
+ 	    mhl_mem_free (pname);
  	    return -1;
  	}
  	pqname = name_quote (s, 0);
- 	g_free (s);
+ 	mhl_mem_free (s);
      } else {
  	pqname = name_quote (pname, 0);
      }
-     g_free (pname);
+     mhl_mem_free (pname);
  
  #define COPY_CHAR \
      if ((size_t) (t-pad) > sizeof(pad)) { \
- 	g_free (pqname); \
+ 	mhl_mem_free (pqname); \
  	return -1; \
      } \
      else \
@@@ -110,7 -110,7 +111,7 @@@
  
  #define COPY_STRING(a) \
      if ((t-pad)+strlen(a)>sizeof(pad)) { \
- 	g_free (pqname); \
+ 	mhl_mem_free (pqname); \
  	return -1; \
      } else { \
  	strcpy (t, a); \
@@@ -146,7 -146,7 +147,7 @@@
  	}
      }
  
-     g_free (pqname);
+     mhl_mem_free (pqname);
      open_error_pipe ();
      if (my_system (EXECUTE_AS_SHELL, "/bin/sh", pad)) {
  	close_error_pipe (D_ERROR, NULL);
@@@ -182,7 -182,7 +183,7 @@@ sfs_redirect (struct vfs_class *me, con
  
      if (!sfs_vfmake (me, name, cache)) {
  	cur = g_new (struct cachedfile, 1);
 -	cur->name = g_strdup (name);
 +	cur->name = mhl_str_dup (name);
  	cur->cache = cache;
  	cur->next = head;
  	head = cur;
@@@ -193,7 -193,7 +194,7 @@@
      }
  
      unlink (cache);
-     g_free (cache);
+     mhl_mem_free (cache);
      return "/I_MUST_NOT_EXIST";
  }
  
@@@ -287,9 -287,9 +288,9 @@@ static void sfs_free (vfsid id
      else
  	head = cur->next;
  
-     g_free (cur->cache);
-     g_free (cur->name);
-     g_free (cur);
+     mhl_mem_free (cur->cache);
+     mhl_mem_free (cur->name);
+     mhl_mem_free (cur);
  }
  
  static void sfs_fill_names (struct vfs_class *me, fill_names_f func)
@@@ -316,7 -316,7 +317,7 @@@ static char 
  sfs_getlocalcopy (struct vfs_class *me, const char *path)
  {
      path = sfs_redirect (me, path);
 -    return g_strdup (path);
 +    return mhl_str_dup (path);
  }
  
  static int
@@@ -338,15 -338,15 +339,15 @@@ static int sfs_init (struct vfs_class *
  
      (void) me;
  
 -    mc_sfsini = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR "sfs.ini");
 +    mc_sfsini = mhl_str_dir_plus_file (mc_home, "extfs" PATH_SEP_STR "sfs.ini");
      cfg = fopen (mc_sfsini, "r");
  
      if (!cfg){
  	fprintf (stderr, _("Warning: file %s not found\n"), mc_sfsini);
- 	g_free (mc_sfsini);
+ 	mhl_mem_free (mc_sfsini);
  	return 0;
      }
-     g_free (mc_sfsini);
+     mhl_mem_free (mc_sfsini);
  
      sfs_no = 0;
      while (sfs_no < MAXFS && fgets (key, sizeof (key), cfg)) {
@@@ -391,8 -391,8 +392,8 @@@
  	if ((semi = strchr (c, '\n')))
  	    *semi = 0;
  
 -	sfs_prefix [sfs_no] = g_strdup (key);
 -	sfs_command [sfs_no] = g_strdup (c);
 +	sfs_prefix [sfs_no] = mhl_str_dup (key);
 +	sfs_command [sfs_no] = mhl_str_dup (c);
  	sfs_flags [sfs_no] = flags;
  	sfs_no++;
      }
@@@ -408,8 -408,8 +409,8 @@@ sfs_done (struct vfs_class *me
      (void) me;
  
      for (i = 0; i < sfs_no; i++){
-         g_free (sfs_prefix [i]);
- 	g_free (sfs_command [i]);
+         mhl_mem_free (sfs_prefix [i]);
+ 	mhl_mem_free (sfs_command [i]);
  	sfs_prefix [i] = sfs_command [i] = NULL;
      }
      sfs_no = 0;
diff --combined vfs/smbfs.c
index a4e5050,d891120..db0d945
--- a/vfs/smbfs.c
+++ b/vfs/smbfs.c
@@@ -22,13 -22,9 +22,13 @@@
  
  /* Namespace: exports init_smbfs, smbfs_set_debug(), smbfs_set_debugf() */
  #include <config.h>
 +
  #include <stdio.h>
  #include <sys/types.h>
  
 +#include <mhl/types.h>
 +#include <mhl/string.h>
 +
  #undef	USE_NCURSES	/* Don't include *curses.h */
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -53,8 -49,6 +53,8 @@@
  
  #include <string.h>
  
 +#include <mhl/string.h>
 +
  #include "vfs.h"
  #include "vfs-impl.h"
  #include "smbfs.h"
@@@ -74,8 -68,8 +74,8 @@@ extern struct in_addr ipzero
  static mode_t myumask = 0755;
  extern pstring global_myname;
  static int smbfs_open_connections = 0;
 -static gboolean got_user = FALSE;
 -static gboolean got_pass = FALSE;
 +static bool got_user = FALSE;
 +static bool got_pass = FALSE;
  static pstring password;
  static pstring username;
  static struct vfs_class vfs_smbfs_ops;
@@@ -112,13 -106,13 +112,13 @@@ typedef struct 
  static GSList *auth_list;
  
  /* this function allows you to write:
 - * char *s = g_strdup("hello, world");
 + * char *s = mhl_str_dup("hello, world");
   * s = free_after(g_strconcat(s, s, (char *)0), s);
   */
  static inline char *
  free_after (char *result, char *string_to_free)
  {
- 	g_free(string_to_free);
+ 	mhl_mem_free(string_to_free);
  	return result;
  }
  
@@@ -126,10 -120,10 +126,10 @@@
  static void 
  smbfs_auth_free (struct smb_authinfo const *a)
  {
-     g_free (a->host);
-     g_free (a->share);
-     g_free (a->domain);
-     g_free (a->user);
+     mhl_mem_free (a->host);
+     mhl_mem_free (a->share);
+     mhl_mem_free (a->domain);
+     mhl_mem_free (a->user);
      wipe_password (a->password);
  }
  
@@@ -182,12 -176,12 +182,12 @@@ smbfs_auth_add (const char *host, cons
      if (!auth)
          return;
  
 -    /* Don't check for NULL, g_strdup already does. */
 -    auth->host = g_strdup (host);
 -    auth->share = g_strdup (share);
 -    auth->domain = g_strdup (domain);
 -    auth->user = g_strdup (user);
 -    auth->password = g_strdup (password);
 +    /* Don't check for NULL, mhl_str_dup already does. */
 +    auth->host = mhl_str_dup (host);
 +    auth->share = mhl_str_dup (share);
 +    auth->domain = mhl_str_dup (domain);
 +    auth->user = mhl_str_dup (user);
 +    auth->password = mhl_str_dup (password);
      auth_list = g_slist_prepend (auth_list, auth);
  }
  
@@@ -198,13 -192,13 +198,13 @@@ smbfs_auth_remove (const char *host, co
      struct smb_authinfo *auth;
      GSList *list;
  
 -    data.host = g_strdup (host);
 -    data.share = g_strdup (share);
 +    data.host = mhl_str_dup (host);
 +    data.share = mhl_str_dup (share);
      list = g_slist_find_custom (auth_list, 
                                  &data, 
                                  smbfs_auth_cmp_host_and_share);
-     g_free (data.host);
-     g_free (data.share);
+     mhl_mem_free (data.host);
+     mhl_mem_free (data.share);
      if (!list)
          return;
      auth = list->data;
@@@ -225,12 -219,12 +225,12 @@@ smbfs_bucket_set_authinfo (smbfs_connec
      GSList *list;
  
      if (domain && user && pass) {
-         g_free (bucket->domain);
-         g_free (bucket->user);
-         g_free (bucket->password);
+         mhl_mem_free (bucket->domain);
+         mhl_mem_free (bucket->user);
+         mhl_mem_free (bucket->password);
 -        bucket->domain = g_strdup (domain);
 -        bucket->user = g_strdup (user);
 -        bucket->password = g_strdup (pass);
 +        bucket->domain = mhl_str_dup (domain);
 +        bucket->user = mhl_str_dup (user);
 +        bucket->password = mhl_str_dup (pass);
          smbfs_auth_remove (bucket->host, bucket->service);
          smbfs_auth_add (bucket->host, bucket->service,
                    domain, user, pass);
@@@ -244,16 -238,16 +244,16 @@@
          list = g_slist_find_custom (auth_list, &data, smbfs_auth_cmp_host);
      if (list) {
          auth = list->data;
 -        bucket->domain = g_strdup (auth->domain);
 -        bucket->user = g_strdup (auth->user);
 -        bucket->password = g_strdup (auth->password);
 +        bucket->domain = mhl_str_dup (auth->domain);
 +        bucket->user = mhl_str_dup (auth->user);
 +        bucket->password = mhl_str_dup (auth->password);
          return 1;
      }
  
      if (got_pass) {
 -        bucket->domain = g_strdup (lp_workgroup ());
 -        bucket->user = g_strdup (got_user ? username : user);
 -        bucket->password = g_strdup (password);
 +        bucket->domain = mhl_str_dup (lp_workgroup ());
 +        bucket->user = mhl_str_dup (got_user ? username : user);
 +        bucket->password = mhl_str_dup (password);
          return 1;
      }
  
@@@ -262,12 -256,12 +262,12 @@@
  				 (domain ? domain : lp_workgroup ()),
  				 user);
      if (auth) {
-         g_free (bucket->domain);
-         g_free (bucket->user);
-         g_free (bucket->password);
+         mhl_mem_free (bucket->domain);
+         mhl_mem_free (bucket->user);
+         mhl_mem_free (bucket->password);
 -        bucket->domain = g_strdup (auth->domain);
 -        bucket->user = g_strdup (auth->user);
 -        bucket->password = g_strdup (auth->password);
 +        bucket->domain = mhl_str_dup (auth->domain);
 +        bucket->user = mhl_str_dup (auth->user);
 +        bucket->password = mhl_str_dup (auth->password);
          smbfs_auth_remove (bucket->host, bucket->service);
          auth_list = g_slist_prepend (auth_list, auth);
          return 1;
@@@ -363,7 -357,7 +363,7 @@@ smbfs_fill_names (struct vfs_class *me
  		"/", smbfs_connections[i].service,
  		NULL);
  	    (*func)(path);
- 	    g_free (path);
+ 	    mhl_mem_free (path);
  	}
      }
  }
@@@ -439,7 -433,7 +439,7 @@@ typedef struct dir_entry 
  } dir_entry;
  
  typedef struct {
 -    gboolean server_list;
 +    bool server_list;
      char *dirname;
      char *path;			/* the dir originally passed to smbfs_opendir */
      smbfs_connection *conn;
@@@ -453,7 -447,7 +453,7 @@@ static opendir_inf
  	*current_share_info,
  	*current_server_info;
  
 -static gboolean first_direntry;
 +static bool first_direntry;
  
  static dir_entry *
  smbfs_new_dir_entry (const char *name)
@@@ -461,7 -455,7 +461,7 @@@
      static int inode_counter;
      dir_entry *new_entry;
      new_entry = g_new0 (dir_entry, 1);
 -    new_entry->text = dos_to_unix (g_strdup (name), 1);
 +    new_entry->text = dos_to_unix (mhl_str_dup (name), 1);
  
      if (first_direntry) {
  	current_info->entries = new_entry;
@@@ -552,7 -546,7 +552,7 @@@ smbfs_loaddir_helper (file_info * finfo
  
  /* takes "/foo/bar/file" and gives malloced "\\foo\\bar\\file" */
  static char *
 -smbfs_convert_path (const char *remote_file, gboolean trailing_asterik)
 +smbfs_convert_path (const char *remote_file, bool trailing_asterik)
  {
      const char *p, *my_remote;
      char *result;
@@@ -603,19 -597,19 +603,19 @@@ smbfs_reconnect(smbfs_connection *conn
  	DEBUG(3, ("RECONNECT\n"));
  
  	if (*(conn->host) == 0)
 -		host = g_strdup(conn->cli->desthost);		/* server browsing */
 +		host = mhl_str_dup(conn->cli->desthost);		/* server browsing */
  	else
 -		host = g_strdup(conn->host);
 +		host = mhl_str_dup(conn->host);
  
  	cli_shutdown(conn->cli);
  
     	if (!(conn->cli = smbfs_do_connect(host, conn->service))) {
  		message (D_ERROR, MSG_ERROR,
  			_(" reconnect to %s failed\n "), conn->host);
- 		g_free(host);
+ 		mhl_mem_free(host);
  		return False;
  	}
- 	g_free(host);
+ 	mhl_mem_free(host);
  	if (++(*retries) == 2)
  		return False;
  	return True;
@@@ -765,7 -759,7 +765,7 @@@ smbfs_loaddir (opendir_info *smbfs_info
      /* do regular directory listing */
      if (strncmp (smbfs_info->conn->service, info_dirname + 1, servlen) == 0) {
  	/* strip share name from dir */
 -	my_dirname = g_strdup (info_dirname + servlen);
 +	my_dirname = mhl_str_dup (info_dirname + servlen);
  	*my_dirname = '/';
  	my_dirname = free_after(smbfs_convert_path (my_dirname, TRUE), my_dirname);
      } else
@@@ -783,12 -777,12 +783,12 @@@
  	 smbfs_loaddir_helper, NULL) < 0) {
  	/* cli_list returns -1 if directory empty or cannot read socket */
  	my_errno = cli_error (smbfs_info->conn->cli, NULL, &err, NULL);
- 	g_free (my_dirname);
+ 	mhl_mem_free (my_dirname);
  	return 0;
      }
      if (*(my_dirname) == 0)
  	smbfs_info->dirname = smbfs_info->conn->service;
-     g_free (my_dirname);
+     mhl_mem_free (my_dirname);
  /*	do_dskattr();	*/
  
    done:
@@@ -805,8 -799,8 +805,8 @@@ smbfs_free_dir (dir_entry *de
      if (!de) return;
  
      smbfs_free_dir (de->next);
-     g_free (de->text);
-     g_free (de);
+     mhl_mem_free (de->text);
+     mhl_mem_free (de);
  }
  #endif
  
@@@ -855,10 -849,10 +855,10 @@@ smbfs_closedir (void *info
  /*    for (p = smbfs_info->entries; p;){
  		q = p;
  		p = p->next;
- 		g_free (q->text);
- 		g_free (q);
+ 		mhl_mem_free (q->text);
+ 		mhl_mem_free (q);
      }
-     g_free (info);	*/
+     mhl_mem_free (info);	*/
      return 0;
  }
  
@@@ -1034,7 -1028,7 +1034,7 @@@ smbfs_get_master_browser(char **host
  		if (!count)
  			return 0;
  		/* just return first master browser */
 -		*host = g_strdup(inet_ntoa(ip_list[0]));
 +		*host = mhl_str_dup(inet_ntoa(ip_list[0]));
  		return 1;
  	}
  	return 0;
@@@ -1043,12 -1037,12 +1043,12 @@@
  static void 
  smbfs_free_bucket (smbfs_connection *bucket)
  {
- 	g_free (bucket->host);
- 	g_free (bucket->service);
- 	g_free (bucket->domain);
- 	g_free (bucket->user);
+ 	mhl_mem_free (bucket->host);
+ 	mhl_mem_free (bucket->service);
+ 	mhl_mem_free (bucket->domain);
+ 	mhl_mem_free (bucket->user);
  	wipe_password (bucket->password);
- 	g_free (bucket->home);
+ 	mhl_mem_free (bucket->home);
  	memset (bucket, 0, sizeof (smbfs_connection));
  }
  
@@@ -1148,16 -1142,16 +1148,16 @@@ smbfs_open_link (char *host, char *path
      }
      current_bucket = bucket;
  
 -    bucket->user = g_strdup (user);
 -    bucket->service = g_strdup (service);
 +    bucket->user = mhl_str_dup (user);
 +    bucket->service = mhl_str_dup (service);
  
      if (!(*host)) {		/* if blank host name, browse for servers */
  	if (!smbfs_get_master_browser (&host))	/* set host to ip of master browser */
  	    return 0;		/* could not find master browser? */
- 	g_free (host);
+ 	mhl_mem_free (host);
 -	bucket->host = g_strdup ("");	/* blank host means master browser */
 +	bucket->host = mhl_str_dup ("");	/* blank host means master browser */
      } else
 -	bucket->host = g_strdup (host);
 +	bucket->host = mhl_str_dup (host);
  
      if (!smbfs_bucket_set_authinfo (bucket, 0,	/* domain currently not used */
  			      user, this_pass, 1))
@@@ -1201,11 -1195,11 +1201,11 @@@ smbfs_get_path (smbfs_connection ** sc
  	 smbfs_get_host_and_username (&path, &host, &user, &port, &pass)))
  	if ((*sc =
  	     smbfs_open_link (host, remote_path, user, &port, pass)) == NULL) {
- 	    g_free (remote_path);
+ 	    mhl_mem_free (remote_path);
  	    remote_path = NULL;
  	}
-     g_free (host);
-     g_free (user);
+     mhl_mem_free (host);
+     mhl_mem_free (user);
      if (pass)
  	wipe_password (pass);
  
@@@ -1217,8 -1211,8 +1217,8 @@@
  	int f = !strcmp (remote_path, "/~");
  	if (f || !strncmp (remote_path, "/~/", 3)) {
  	    char *s;
 -	    s = concat_dir_and_file ((*sc)->home, remote_path + 3 - f);
 +	    s = mhl_str_dir_plus_file ((*sc)->home, remote_path + 3 - f);
- 	    g_free (remote_path);
+ 	    mhl_mem_free (remote_path);
  	    return s;
  	}
      }
@@@ -1254,7 -1248,7 +1254,7 @@@ smbfs_opendir (struct vfs_class *me, co
      /* FIXME: where freed? */
      smbfs_info = g_new (opendir_info, 1);
  	smbfs_info->server_list = FALSE;
 -    smbfs_info->path = g_strdup(dirname);		/* keep original */
 +    smbfs_info->path = mhl_str_dup(dirname);		/* keep original */
  	smbfs_info->dirname = remote_dir;
      smbfs_info->conn = sc;
      smbfs_info->entries = 0;
@@@ -1308,7 -1302,7 +1308,7 @@@ smbfs_fake_share_stat (const char *serv
  	smbfs_connection *sc;
  	char *p;
  	p = smbfs_get_path (&sc, path);
- 	g_free (p);
+ 	mhl_mem_free (p);
  	if (p) {
  	    memset (buf, 0, sizeof (*buf));
  	    /*      show this as dir        */
@@@ -1362,7 -1356,7 +1362,7 @@@ smbfs_get_remote_stat (smbfs_connectio
  #if 0	/* single_entry is never free()d now.  And only my_stat is used */
      single_entry = g_new (dir_entry, 1);
  
 -    single_entry->text = dos_to_unix (g_strdup (finfo->name), 1);
 +    single_entry->text = dos_to_unix (mhl_str_dup (finfo->name), 1);
  
      single_entry->next = 0;
  #endif
@@@ -1372,16 -1366,16 +1372,16 @@@
      if (cli_list
  	(sc->cli, mypath, attribute, smbfs_loaddir_helper, single_entry) < 1) {
  	my_errno = ENOENT;
- 	g_free (mypath);
+ 	mhl_mem_free (mypath);
  	return -1;		/* cli_list returns number of files */
      }
  
      memcpy (buf, &single_entry->my_stat, sizeof (struct stat));
  
  /* don't free here, use for smbfs_fstat() */
- /*	g_free(single_entry->text);
- 	g_free(single_entry);	*/
-     g_free (mypath);
+ /*	mhl_mem_free(single_entry->text);
+ 	mhl_mem_free(single_entry);	*/
+     mhl_mem_free (mypath);
      return 0;
  }
  
@@@ -1430,7 -1424,7 +1430,7 @@@ smbfs_get_stat_info (smbfs_connection 
      {
  	char *mdp;
  	char *mydir;
 -	mdp = mydir = g_strdup (current_info->dirname);
 +	mdp = mydir = mhl_str_dup (current_info->dirname);
  	if ((p = strrchr (mydir, '/')))
  	    *p = 0;		/* advance util last '/' */
  	if ((p = strrchr (mydir, '/')))
@@@ -1439,11 -1433,11 +1439,11 @@@
  	    memset (buf, 0, sizeof (struct stat));
  	    buf->st_mode = (S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH) & myumask;
  	    memcpy (&single_entry->my_stat, buf, sizeof (struct stat));
- 	    g_free (mdp);
+ 	    mhl_mem_free (mdp);
  	    DEBUG (1, ("	PARENT:found in %s\n", current_info->dirname));
  	    return 0;
  	}
- 	g_free (mdp);
+ 	mhl_mem_free (mdp);
      }
      /* now try to identify as CURRENT dir? */
      {
@@@ -1501,7 -1495,7 +1501,7 @@@ smbfs_chdir (struct vfs_class *me, cons
      DEBUG (3, ("smbfs_chdir(path:%s)\n", path));
      if (!(remote_dir = smbfs_get_path (&sc, path)))
  	return -1;
-     g_free (remote_dir);
+     mhl_mem_free (remote_dir);
  
      return 0;
  }
@@@ -1512,7 -1506,7 +1512,7 @@@ smbfs_loaddir_by_name (struct vfs_clas
  	void *info;
  	char *mypath, *p;
  
 -	mypath = g_strdup(path);
 +	mypath = mhl_str_dup(path);
  	p = strrchr(mypath, '/');
  
  	if (p > mypath)
@@@ -1520,7 -1514,7 +1520,7 @@@
  	DEBUG(6, ("smbfs_loaddir_by_name(%s)\n", mypath));
  	smbfs_chdir(me, mypath);
  	info = smbfs_opendir (me, mypath);
- 	g_free(mypath);
+ 	mhl_mem_free(mypath);
  	if (!info)
  		return -1;
  	smbfs_readdir(info);
@@@ -1598,7 -1592,7 +1598,7 @@@ smbfs_stat (struct vfs_class * me, cons
  	    DEBUG (1, ("smbfs_stat: showing server as directory\n"));
  	    memset (buf, 0, sizeof (struct stat));
  	    buf->st_mode = (S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH) & myumask;
- 	    g_free (service);
+ 	    mhl_mem_free (service);
  	    return 0;
  	}
      }
@@@ -1619,12 -1613,12 +1619,12 @@@
      if (strncmp (p, pp, strlen (p)) != 0) {
  	DEBUG (6, ("desired '%s' is not loaded, we have '%s'\n", p, pp));
  	if (smbfs_loaddir_by_name (me, path) < 0) {
- 	    g_free (service);
+ 	    mhl_mem_free (service);
  	    return -1;
  	}
  	DEBUG (6, ("loaded dir: '%s'\n", current_info->dirname));
      }
-     g_free (service);
+     mhl_mem_free (service);
      /* stat dirs & files under shares now */
      return smbfs_get_stat_info (sc, path, buf);
  }
@@@ -1686,17 -1680,17 +1686,17 @@@ smbfs_mkdir (struct vfs_class * me, con
      DEBUG (3, ("smbfs_mkdir(path:%s, mode:%d)\n", path, (int) mode));
      if ((remote_file = smbfs_get_path (&sc, path)) == 0)
  	return -1;
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
      cpath = smbfs_convert_path (path, FALSE);
  
      if (!cli_mkdir (sc->cli, cpath)) {
  	my_errno = cli_error (sc->cli, NULL, &err, NULL);
  	message (D_ERROR, MSG_ERROR, _(" Error %s creating directory %s "),
  		    cli_errstr (sc->cli), CNV_LANG (cpath));
- 	g_free (cpath);
+ 	mhl_mem_free (cpath);
  	return -1;
      }
-     g_free (cpath);
+     mhl_mem_free (cpath);
      return 0;
  }
  
@@@ -1712,18 -1706,18 +1712,18 @@@ smbfs_rmdir (struct vfs_class *me, cons
  	DEBUG(3, ("smbfs_rmdir(path:%s)\n", path));
  	if ((remote_file = smbfs_get_path (&sc, path)) == 0)
  		return -1;
- 	g_free (remote_file);
+ 	mhl_mem_free (remote_file);
  	cpath = smbfs_convert_path (path, FALSE);
  
  	if (!cli_rmdir(sc->cli, cpath)) {
  		my_errno = cli_error(sc->cli, NULL, &err, NULL);
  		message (D_ERROR, MSG_ERROR, _(" Error %s removing directory %s "), 
  			cli_errstr(sc->cli), CNV_LANG(cpath));
- 		g_free (cpath);
+ 		mhl_mem_free (cpath);
  		return -1;
  	} 
  
- 	g_free (cpath);
+ 	mhl_mem_free (cpath);
  	return 0;
  }
  
@@@ -1763,7 -1757,7 +1763,7 @@@ smbfs_forget (const char *path
  	path += 2;
  
      if ((p = smbfs_get_host_and_username (&path, &host, &user, &port, NULL))) {
- 	g_free (p);
+ 	mhl_mem_free (p);
  	for (i = 0; i < SMBFS_MAX_CONNECTIONS; i++) {
  	    if (smbfs_connections[i].cli
  		&& (strcmp (host, smbfs_connections[i].host) == 0)
@@@ -1779,8 -1773,8 +1779,8 @@@
  	    }
  	}
      }
-     g_free (host);
-     g_free (user);
+     mhl_mem_free (host);
+     mhl_mem_free (user);
  }
  
  static int
@@@ -1877,9 -1871,9 +1877,9 @@@ smbfs_open (struct vfs_class *me, cons
  
      ret = smbfs_open_readwrite (remote_handle, remote_file, flags, mode);
  
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
      if (!ret)
- 	g_free (remote_handle);
+ 	mhl_mem_free (remote_handle);
  
      return ret;
  }
@@@ -1900,10 -1894,10 +1900,10 @@@ smbfs_unlink (struct vfs_class *me, con
      if (!cli_unlink(sc->cli, remote_file)) {
  	message (D_ERROR, MSG_ERROR, _(" %s removing remote file %s "), 
  			cli_errstr(sc->cli), CNV_LANG(remote_file));
- 	g_free (remote_file);
+ 	mhl_mem_free (remote_file);
  	return -1;
      }   
-     g_free (remote_file);
+     mhl_mem_free (remote_file);
      return 0;
  }
  
@@@ -1920,7 -1914,7 +1920,7 @@@ smbfs_rename (struct vfs_class *me, con
  	return -1;
   
      if ((rb = smbfs_get_path (&sc, b)) == 0) {
- 	g_free (ra);
+ 	mhl_mem_free (ra);
  	return -1;
      }
  
@@@ -1929,8 -1923,8 +1929,8 @@@
  
      retval = cli_rename(sc->cli, ra, rb);
  
-     g_free (ra);
-     g_free (rb);
+     mhl_mem_free (ra);
+     mhl_mem_free (rb);
  
      if (!retval) {
  	message (D_ERROR, MSG_ERROR, _(" %s renaming files\n"), 
diff --combined vfs/tar.c
index 12a4c8f,6e0b885..eda0e7a
--- a/vfs/tar.c
+++ b/vfs/tar.c
@@@ -22,19 -22,17 +22,21 @@@
  /* Namespace: init_tarfs */
  
  #include <config.h>
 +
  #include <sys/types.h>
  #include <errno.h>
  #include <ctype.h>
  
 +#include <mhl/memory.h>
 +#include <mhl/string.h>
 +
  #ifdef hpux
  /* major() and minor() macros (among other things) defined here for hpux */
  #include <sys/mknod.h>
  #endif
  
+ #include <mhl/memory.h>
+ 
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
  #include "../src/wtools.h"	/* message() */
@@@ -231,7 -229,7 +233,7 @@@ tar_open_archive_int (struct vfs_class 
  	ERRNOR (ENOENT, -1);
      }
  
 -    archive->name = g_strdup (name);
 +    archive->name = mhl_str_dup (name);
      mc_stat (name, &(archive->u.arch.st));
      archive->u.arch.fd = -1;
      archive->u.arch.type = TAR_UNKNOWN;
@@@ -246,7 -244,7 +248,7 @@@
  	result = mc_open (s, O_RDONLY);
  	if (result == -1)
  	    message (D_ERROR, MSG_ERROR, _("Cannot open tar archive\n%s"), s);
- 	g_free (s);
+ 	mhl_mem_free (s);
  	if (result == -1)
  	    ERRNOR (ENOENT, -1);
      }
@@@ -494,13 -492,13 +496,13 @@@ tar_read_header (struct vfs_class *me, 
  	longp = ((header->header.linkflag == LF_LONGNAME)
  		 ? &next_long_name : &next_long_link);
  
- 	g_free (*longp);
+ 	mhl_mem_free (*longp);
  	bp = *longp = g_malloc (*h_size + 1);
  
  	for (size = *h_size; size > 0; size -= written) {
  	    data = tar_get_next_record (archive, tard)->charptr;
  	    if (data == NULL) {
- 		g_free (*longp);
+ 		mhl_mem_free (*longp);
  		*longp = NULL;
  		message (D_ERROR, MSG_ERROR,
  			 _("Unexpected EOF on archive file"));
@@@ -515,7 -513,7 +517,7 @@@
  	}
  
  	if (bp - *longp == MC_MAXPATHLEN && bp[-1] != '\0') {
- 	    g_free (*longp);
+ 	    mhl_mem_free (*longp);
  	    *longp = NULL;
  	    message (D_ERROR, MSG_ERROR, _("Inconsistent tar archive"));
  	    return STATUS_BADCHECKSUM;
@@@ -560,8 -558,8 +562,8 @@@
  					  PREFIX_SIZE);
  		current_file_name = g_strconcat (temp_prefix, PATH_SEP_STR,
  						 temp_name, (char *) NULL);
- 		g_free (temp_name);
- 		g_free (temp_prefix);
+ 		mhl_mem_free (temp_name);
+ 		mhl_mem_free (temp_prefix);
  	    }
  	    break;
  	case TAR_GNU:
@@@ -605,7 -603,7 +607,7 @@@
  	    } else {
  		entry = vfs_s_new_entry (me, p, inode);
  		vfs_s_insert_entry (me, parent, entry);
- 		g_free (current_link_name);
+ 		mhl_mem_free (current_link_name);
  		goto done;
  	    }
  	}
@@@ -617,12 -615,12 +619,12 @@@
  	if (*current_link_name) {
  	    inode->linkname = current_link_name;
  	} else if (current_link_name != next_long_link) {
- 	    g_free (current_link_name);
+ 	    mhl_mem_free (current_link_name);
  	}
  	entry = vfs_s_new_entry (me, p, inode);
  
  	vfs_s_insert_entry (me, parent, entry);
- 	g_free (current_file_name);
+ 	mhl_mem_free (current_file_name);
  
        done:
  	next_long_link = next_long_name = NULL;
diff --combined vfs/undelfs.c
index 00afcaf,255bb8d..f4f5141
--- a/vfs/undelfs.c
+++ b/vfs/undelfs.c
@@@ -51,7 -51,7 +51,8 @@@
  #include <ext2fs/ext2fs.h>
  #include <ctype.h>
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -100,11 -100,11 +101,11 @@@ undelfs_shutdown (void
      if (fs)
  	ext2fs_close (fs);
      fs = NULL;
-     g_free (ext2_fname);
+     mhl_mem_free (ext2_fname);
      ext2_fname = NULL;
-     g_free (delarray);
+     mhl_mem_free (delarray);
      delarray = NULL;
-     g_free (block_buf);
+     mhl_mem_free (block_buf);
      block_buf = NULL;
  }
  
@@@ -142,15 -142,15 +143,15 @@@ undelfs_get_path (const char *dirname, 
  	if (*p == '/'){
  	    char *tmp;
  
 -	    *file = g_strdup (p+1);
 +	    *file = mhl_str_dup (p+1);
  	    tmp = g_strndup (dirname, p - dirname);
  	    *fsname = g_strconcat ("/dev/", tmp, (char *) NULL);
- 	    g_free (tmp);
+ 	    mhl_mem_free (tmp);
  	    return;
  	}
  	p--;
      }
 -    *file = g_strdup ("");
 +    *file = mhl_str_dup ("");
      *fsname = g_strconcat ("/dev/", dirname, (char *) NULL);
      return;
  }
@@@ -275,10 -275,10 +276,10 @@@ undelfs_loaddel (void
    error_out:
      ext2fs_close_inode_scan (scan);
    free_block_buf:
-     g_free (block_buf);
+     mhl_mem_free (block_buf);
      block_buf = NULL;
    free_delarray:
-     g_free (delarray);
+     mhl_mem_free (delarray);
      delarray = NULL;
      return 0;
  }
@@@ -300,7 -300,7 +301,7 @@@ com_err (const char *whoami, long err_c
  
      message (D_ERROR, _(" Ext2lib error "), " %s (%s: %ld) ", str, whoami,
  	     err_code);
-     g_free (str);
+     mhl_mem_free (str);
  }
  
  static void *
@@@ -313,7 -313,7 +314,7 @@@ undelfs_opendir (struct vfs_class *me, 
  	return 0;
  
      /* We don't use the file name */
-     g_free (f);
+     mhl_mem_free (f);
      
      if (!ext2_fname || strcmp (ext2_fname, file)){
  	undelfs_shutdown ();
@@@ -321,7 -321,7 +322,7 @@@
      } else {
  	/* To avoid expensive re-scannings */
  	readdir_ptr = READDIR_PTR_INIT;
- 	g_free (file);
+ 	mhl_mem_free (file);
  	return fs;
      }
  
@@@ -369,7 -369,7 +370,7 @@@ undelfs_readdir(void *vfs_info
      if (readdir_ptr < 0)
  	strcpy (dirent_dest, readdir_ptr == -2 ? "." : "..");
      else
 -	g_snprintf(dirent_dest, MC_MAXPATHLEN, "%ld:%d",
 +	snprintf(dirent_dest, MC_MAXPATHLEN, "%ld:%d",
  		   (long) delarray[readdir_ptr].ino,
  		   delarray[readdir_ptr].num_blocks);
      readdir_ptr++;
@@@ -417,8 -417,8 +418,8 @@@ undelfs_open (struct vfs_class *me, con
      if (!ext2_fname || strcmp (ext2_fname, file)) {
  	message (D_ERROR, undelfserr,
  		 _(" You have to chdir to extract files first "));
- 	g_free (file);
- 	g_free (f);
+ 	mhl_mem_free (file);
+ 	mhl_mem_free (f);
  	return 0;
      }
      inode = atol (f);
@@@ -431,15 -431,15 +432,15 @@@
  	/* Found: setup all the structures needed by read */
  	p = (undelfs_file *) g_try_malloc (((gsize) sizeof (undelfs_file)));
  	if (!p) {
- 	    g_free (file);
- 	    g_free (f);
+ 	    mhl_mem_free (file);
+ 	    mhl_mem_free (f);
  	    return 0;
  	}
  	p->buf = g_try_malloc (fs->blocksize);
  	if (!p->buf) {
- 	    g_free (p);
- 	    g_free (file);
- 	    g_free (f);
+ 	    mhl_mem_free (p);
+ 	    mhl_mem_free (file);
+ 	    mhl_mem_free (f);
  	    return 0;
  	}
  	p->inode = inode;
@@@ -449,8 -449,8 +450,8 @@@
  	p->pos = 0;
  	p->size = delarray[i].size;
      }
-     g_free (file);
-     g_free (f);
+     mhl_mem_free (file);
+     mhl_mem_free (f);
      undelfs_usage++;
      return p;
  }
@@@ -459,8 -459,8 +460,8 @@@ static 	in
  undelfs_close (void *vfs_info)
  {
      undelfs_file *p = vfs_info;
-     g_free (p->buf);
-     g_free (p);
+     mhl_mem_free (p->buf);
+     mhl_mem_free (p);
      undelfs_usage--;
      return 0;
  }
@@@ -594,20 -594,20 +595,20 @@@ undelfs_lstat (struct vfs_class *me, co
  	    f    = "sda1"                     f   ="401:1"
         If the first char in f is no digit -> return error */
      if (!isdigit (*f)) {
- 	g_free (file);
- 	g_free (f);
+ 	mhl_mem_free (file);
+ 	mhl_mem_free (f);
  	return -1;
      }
  	
      if (!ext2_fname || strcmp (ext2_fname, file)){
  	message (D_ERROR, undelfserr, _(" You have to chdir to extract files first "));
- 	g_free (file);
- 	g_free (f);
+ 	mhl_mem_free (file);
+ 	mhl_mem_free (f);
  	return 0;
      }
      inode_index = undelfs_getindex (f);
-     g_free (file);
-     g_free (f);
+     mhl_mem_free (file);
+     mhl_mem_free (f);
  
      if (inode_index == -1)
  	return -1;
@@@ -640,13 -640,13 +641,13 @@@ undelfs_chdir(struct vfs_class *me, con
      /* our vfs, but that is left as an excercise for the reader */
      if ((fd = open (file, O_RDONLY)) == -1){
  	message (D_ERROR, undelfserr, _(" Cannot open file %s "), file);
- 	g_free (f);
- 	g_free (file);
+ 	mhl_mem_free (f);
+ 	mhl_mem_free (file);
  	return -1;
      }
      close (fd);
-     g_free (f);
-     g_free (file);
+     mhl_mem_free (f);
+     mhl_mem_free (file);
      return 0;
  }
  
@@@ -666,8 -666,8 +667,8 @@@ undelfs_getid (struct vfs_class *me, co
  
      if (!fsname)
  	return NULL;
-     g_free (fname);
-     g_free (fsname);
+     mhl_mem_free (fname);
+     mhl_mem_free (fsname);
      return (vfsid) fs;
  }
  
diff --combined vfs/utilvfs.c
index 944d6e1,3f019ac..980141d
--- a/vfs/utilvfs.c
+++ b/vfs/utilvfs.c
@@@ -22,8 -22,7 +22,9 @@@
  
  #include <ctype.h>
  
 +#include <mhl/types.h>
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -59,7 -58,7 +60,7 @@@ vfs_split_url (const char *path, char *
      struct passwd *passwd_info;
      char *dir, *colon, *inner_colon, *at, *rest;
      char *retval;
 -    char * const pcopy = g_strdup (path);
 +    char * const pcopy = mhl_str_dup (path);
      const char *pend = pcopy + strlen (pcopy);
  
      if (pass)
@@@ -74,10 -73,10 +75,10 @@@
  	while (*dir != PATH_SEP && *dir)
  	    dir++;
  	if (*dir) {
 -	    retval = g_strdup (dir);
 +	    retval = mhl_str_dup (dir);
  	    *dir = 0;
  	} else
 -	    retval = g_strdup (PATH_SEP_STR);
 +	    retval = mhl_str_dup (PATH_SEP_STR);
      }
  
      /* search for any possible user */
@@@ -91,10 -90,10 +92,10 @@@
  	    *inner_colon = 0;
  	    inner_colon++;
  	    if (pass)
 -		*pass = g_strdup (inner_colon);
 +		*pass = mhl_str_dup (inner_colon);
  	}
  	if (*pcopy != 0)
 -	    *user = g_strdup (pcopy);
 +	    *user = mhl_str_dup (pcopy);
  
  	if (pend == at + 1)
  	    rest = at;
@@@ -106,10 -105,10 +107,10 @@@
      if (!*user && !(flags & URL_ALLOW_ANON)) {
  	passwd_info = getpwuid (geteuid ());
  	if (passwd_info && passwd_info->pw_name)
 -	    *user = g_strdup (passwd_info->pw_name);
 +	    *user = mhl_str_dup (passwd_info->pw_name);
  	else {
  	    /* This is very unlikely to happen */
 -	    *user = g_strdup ("anonymous");
 +	    *user = mhl_str_dup ("anonymous");
  	}
  	endpwent ();
      }
@@@ -135,9 -134,9 +136,9 @@@
  	}
      }
      if (host)
 -	*host = g_strdup (rest);
 +	*host = mhl_str_dup (rest);
  
-     g_free (pcopy);
+     mhl_mem_free (pcopy);
      return retval;
  }
  #endif				/* USE_NETCODE */
@@@ -242,7 -241,7 +243,7 @@@ vfs_mkstemps (char **pname, const char 
      *q = 0;
  
      fd = mc_mkstemps (pname, prefix, suffix);
-     g_free (suffix);
+     mhl_mem_free (suffix);
      return fd;
  }
  
@@@ -413,7 -412,7 +414,7 @@@ is_year (char *str, struct tm *tim
      return 1;
  }
  
 -gboolean
 +bool
  vfs_parse_filetype (const char *s, size_t *ret_skipped, mode_t *ret_type)
  {
      mode_t type;
@@@ -450,7 -449,7 +451,7 @@@
      return TRUE;
  }
  
 -gboolean
 +bool
  vfs_parse_fileperms (const char *s, size_t *ret_skipped, mode_t *ret_perms)
  {
      const char *p;
@@@ -520,7 -519,7 +521,7 @@@
      return TRUE;
  }
  
 -gboolean
 +bool
  vfs_parse_filemode (const char *s, size_t *ret_skipped,
  		    mode_t *ret_mode)
  {
@@@ -543,7 -542,7 +544,7 @@@
      return TRUE;
  }
  
 -gboolean
 +bool
  vfs_parse_raw_filemode (const char *s, size_t *ret_skipped,
  		    mode_t *ret_mode)
  {
@@@ -747,7 -746,7 +748,7 @@@ vfs_parse_ls_lga (const char *p, struc
  	s->st_mode |= perms;
      }
  
 -    p_copy = g_strdup (p);
 +    p_copy = mhl_str_dup (p);
      num_cols = vfs_split_text (p_copy);
  
      s->st_nlink = atol (columns[0]);
@@@ -846,7 -845,7 +847,7 @@@
  			   column_ptr[idx2] - column_ptr[idx] - 1);
  	}
  	if (linkname) {
 -	    t = g_strdup (p + column_ptr[idx2 + 1]);
 +	    t = mhl_str_dup (p + column_ptr[idx2 + 1]);
  	    *linkname = t;
  	}
      } else {
@@@ -855,10 -854,10 +856,10 @@@
  	 */
  	if (filename) {
  	    /*
 -	     * filename = g_strdup (columns [idx++]);
 +	     * filename = mhl_str_dup (columns [idx++]);
  	     */
  
 -	    t = g_strdup (p + column_ptr[idx]);
 +	    t = mhl_str_dup (p + column_ptr[idx]);
  	    *filename = t;
  	}
  	if (linkname)
@@@ -873,7 -872,7 +874,7 @@@
  	    t[p] = 0;
      }
  
-     g_free (p_copy);
+     mhl_mem_free (p_copy);
      return 1;
  
    error:
@@@ -888,7 -887,7 +889,7 @@@
  		     _("More parsing errors will be ignored."));
      }
  
-     g_free (p_copy);
+     mhl_mem_free (p_copy);
      return 0;
  }
  
diff --combined vfs/vfs.c
index dba0619,c0d44e9..c373f7f
--- a/vfs/vfs.c
+++ b/vfs/vfs.c
@@@ -21,7 -21,7 +21,7 @@@
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
  /* Warning: funtions like extfs_lstat() have right to destroy any
 - * strings you pass to them. This is acutally ok as you g_strdup what
 + * strings you pass to them. This is acutally ok as you mhl_str_dup what
   * you are passing to them, anyway; still, beware.  */
  
  /* Namespace: exports *many* functions with vfs_ prefix; exports
@@@ -38,7 -38,7 +38,8 @@@
  #include <signal.h>
  #include <ctype.h>	/* is_digit() */
  
+ #include <mhl/memory.h>
 +#include <mhl/string.h>
  
  #include "../src/global.h"
  #include "../src/tty.h"		/* enable/disable interrupt key */
@@@ -188,7 -188,7 +189,7 @@@ vfs_strip_suffix_from_filename (const c
      if (!filename)
  	vfs_die ("vfs_strip_suffix_from_path got NULL: impossible");
  
 -    p = g_strdup (filename);
 +    p = mhl_str_dup (filename);
      if (!(semi = strrchr (p, '#')))
  	return p;
  
@@@ -222,7 -222,7 +223,7 @@@ path_magic (const char *path
  
  /*
   * Splits path '/p1#op/inpath' into inpath,op; returns which vfs it is.
-  * What is left in path is p1. You still want to g_free(path), you DON'T
+  * What is left in path is p1. You still want to mhl_mem_free(path), you DON'T
   * want to free neither *inpath nor *op
   */
  struct vfs_class *
@@@ -300,10 -300,10 +301,10 @@@ struct vfs_class 
  vfs_get_class (const char *pathname)
  {
      struct vfs_class *vfs;
 -    char *path = g_strdup (pathname);
 +    char *path = mhl_str_dup (pathname);
  
      vfs = _vfs_get_class (path);
-     g_free (path);
+     mhl_mem_free (path);
  
      if (!vfs)
  	vfs = localfs_class;
@@@ -337,13 -337,13 +338,13 @@@ mc_open (const char *filename, int flag
          mode = 0;
      
      if (!vfs->open) {
- 	g_free (file);
+ 	mhl_mem_free (file);
  	errno = -EOPNOTSUPP;
  	return -1;
      }
  
      info = (*vfs->open) (vfs, file, flags, mode);	/* open must be supported */
-     g_free (file);
+     mhl_mem_free (file);
      if (!info){
  	errno = ferrno (vfs);
  	return -1;
@@@ -361,7 -361,7 +362,7 @@@ int mc_##name inarg 
      char *mpath = vfs_canon (path); \
      vfs = vfs_get_class (mpath); \
      result = vfs->name ? (*vfs->name)callarg : -1; \
-     g_free (mpath); \
+     mhl_mem_free (mpath); \
      if (result == -1) \
  	errno = vfs->name ? ferrno (vfs) : E_NOTSUPP; \
      return result; \
@@@ -406,13 -406,13 +407,13 @@@ int mc_##name (const char *fname1, cons
      name2 = vfs_canon (fname2); \
      if (vfs != vfs_get_class (name2)){ \
      	errno = EXDEV; \
-     	g_free (name1); \
-     	g_free (name2); \
+     	mhl_mem_free (name1); \
+     	mhl_mem_free (name2); \
  	return -1; \
      } \
      result = vfs->name ? (*vfs->name)(vfs, name1, name2) : -1; \
-     g_free (name1); \
-     g_free (name2); \
+     mhl_mem_free (name1); \
+     mhl_mem_free (name2); \
      if (result == -1) \
          errno = vfs->name ? ferrno (vfs) : E_NOTSUPP; \
      return result; \
@@@ -443,7 -443,7 +444,7 @@@ mc_setctl (const char *path, int ctlop
      mpath = vfs_canon (path);
      vfs = vfs_get_class (mpath);
      result = vfs->setctl ? (*vfs->setctl)(vfs, mpath, ctlop, arg) : 0;
-     g_free (mpath);
+     mhl_mem_free (mpath);
      return result;
  }
  
@@@ -482,7 -482,7 +483,7 @@@ mc_opendir (const char *dirname
      vfs = vfs_get_class (dname);
  
      info = vfs->opendir ? (*vfs->opendir)(vfs, dname) : NULL;
-     g_free (dname);
+     mhl_mem_free (dname);
      if (!info){
          errno = vfs->opendir ? ferrno (vfs) : E_NOTSUPP;
  	return NULL;
@@@ -523,7 -523,7 +524,7 @@@ mc_closedir (DIR *dirp
  
      result = vfs->closedir ? (*vfs->closedir)(vfs_info (handle)) : -1;
      vfs_free_handle (handle);
-     g_free (dirp);
+     mhl_mem_free (dirp);
      return result; 
  }
  
@@@ -533,7 -533,7 +534,7 @@@ int mc_stat (const char *filename, stru
      char *path;
      path = vfs_canon (filename); vfs = vfs_get_class (path);
      result = vfs->stat ? (*vfs->stat) (vfs, path, buf) : -1;
-     g_free (path);
+     mhl_mem_free (path);
      if (result == -1)
  	errno = vfs->name ? ferrno (vfs) : E_NOTSUPP;
      return result;
@@@ -545,7 -545,7 +546,7 @@@ int mc_lstat (const char *filename, str
      char *path;
      path = vfs_canon (filename); vfs = vfs_get_class (path);
      result = vfs->lstat ? (*vfs->lstat) (vfs, path, buf) : -1;
-     g_free (path);
+     mhl_mem_free (path);
      if (result == -1)
  	errno = vfs->name ? ferrno (vfs) : E_NOTSUPP;
      return result;
@@@ -566,7 -566,7 +567,7 @@@ int mc_fstat (int handle, struct stat *
  
  /*
   * Return current directory.  If it's local, reread the current directory
 - * from the OS.  You must g_strdup() whatever this function returns.
 + * from the OS.  You must mhl_str_dup() whatever this function returns.
   */
  static const char *
  _vfs_get_cwd (void)
@@@ -584,11 -584,11 +585,11 @@@
  	    || mc_stat (current_dir, &my_stat2)
  	    || my_stat.st_ino != my_stat2.st_ino
  	    || my_stat.st_dev != my_stat2.st_dev) {
- 	    g_free (current_dir);
+ 	    mhl_mem_free (current_dir);
  	    current_dir = p;
  	    return p;
  	}			/* Otherwise we return current_dir below */
- 	g_free (p);
+ 	mhl_mem_free (p);
      }
      return current_dir;
  }
@@@ -596,7 -596,7 +597,7 @@@
  static void
  vfs_setup_wd (void)
  {
 -    current_dir = g_strdup (PATH_SEP_STR);
 +    current_dir = mhl_str_dup (PATH_SEP_STR);
      _vfs_get_cwd ();
  
      if (strlen (current_dir) > MC_MAXPATHLEN - 2)
@@@ -658,10 -658,10 +659,10 @@@ vfs_canon (const char *path
      if (*path != PATH_SEP){ 
      	char *local, *result;
  
 -	local = concat_dir_and_file (current_dir, path);
 +	local = mhl_str_dir_plus_file (current_dir, path);
  
  	result = vfs_canon (local);
- 	g_free (local);
+ 	mhl_mem_free (local);
  	return result;
      }
  
@@@ -670,7 -670,7 +671,7 @@@
       * /p1/p2#op/.././././p3#op/p4. Good luck.
       */
      {
 -	char *result = g_strdup (path);
 +	char *result = mhl_str_dup (path);
  	canonicalize_pathname (result);
          return result;
      }
@@@ -691,7 -691,7 +692,7 @@@ mc_chdir (const char *path
      new_dir = vfs_canon (path);
      new_vfs = vfs_get_class (new_dir);
      if (!new_vfs->chdir) {
-     	g_free (new_dir);
+     	mhl_mem_free (new_dir);
  	return -1;
      }
  
@@@ -699,7 -699,7 +700,7 @@@
  
      if (result == -1) {
  	errno = ferrno (new_vfs);
- 	g_free (new_dir);
+ 	mhl_mem_free (new_dir);
  	return -1;
      }
  
@@@ -707,7 -707,7 +708,7 @@@
      old_vfs = current_vfs;
  
      /* Actually change directory */
-     g_free (current_dir);
+     mhl_mem_free (current_dir);
      current_dir = new_dir;
      current_vfs = new_vfs;
  
@@@ -741,7 -741,7 +742,7 @@@ vfs_file_class_flags (const char *filen
  
      fname = vfs_canon (filename);
      vfs = vfs_get_class (fname);
-     g_free (fname);
+     mhl_mem_free (fname);
      return vfs->flags;
  }
  
@@@ -786,7 -786,7 +787,7 @@@ mc_def_getlocalcopy (const char *filena
  	close (fdout);
      if (fdin != -1)
  	mc_close (fdin);
-     g_free (tmp);
+     mhl_mem_free (tmp);
      return NULL;
  }
  
@@@ -799,7 -799,7 +800,7 @@@ mc_getlocalcopy (const char *pathname
  
      result = vfs->getlocalcopy ? (*vfs->getlocalcopy)(vfs, path) :
                                   mc_def_getlocalcopy (path);
-     g_free (path);
+     mhl_mem_free (path);
      if (!result)
  	errno = ferrno (vfs);
      return result;
@@@ -862,7 -862,7 +863,7 @@@ mc_ungetlocalcopy (const char *pathname
      return_value = vfs->ungetlocalcopy ? 
              (*vfs->ungetlocalcopy)(vfs, path, local, has_changed) :
              mc_def_ungetlocalcopy (vfs, path, local, has_changed);
-     g_free (path);
+     mhl_mem_free (path);
      return return_value;
  }
  
@@@ -906,7 -906,7 +907,7 @@@ vfs_shut (void
  
      vfs_gc_done ();
  
-     g_free (current_dir);
+     mhl_mem_free (current_dir);
  
      for (vfs = vfs_list; vfs; vfs = vfs->next)
  	if (vfs->done)
@@@ -931,7 -931,7 +932,7 @@@ vfs_fill_names (fill_names_f func
  
  /*
   * Returns vfs path corresponding to given url. If passed string is
 - * not recognized as url, g_strdup(url) is returned.
 + * not recognized as url, mhl_str_dup(url) is returned.
   */
  
  static const struct {
@@@ -955,7 -955,7 +956,7 @@@ vfs_translate_url (const char *url
         if (strncmp (url, url_table[i].name, url_table[i].name_len) == 0)
             return g_strconcat (url_table[i].substitute, url + url_table[i].name_len, (char*) NULL);
  
 -    return g_strdup (url);
 +    return mhl_str_dup (url);
  }
  
  int vfs_file_is_local (const char *filename)

-- 
Midnight Commander Development



More information about the mc-devel mailing list