diff --git a/src/modules/_Charset/charsetmod.c b/src/modules/_Charset/charsetmod.c
index 92db16e2a2325b30c96101ea6ed90d912a32fea1..f059cd9330bf53cbff16d9137b1081e9785debb3 100644
--- a/src/modules/_Charset/charsetmod.c
+++ b/src/modules/_Charset/charsetmod.c
@@ -3,7 +3,7 @@
 #endif /* HAVE_CONFIG_H */
 
 #include "global.h"
-RCSID("$Id: charsetmod.c,v 1.11 1999/03/07 01:12:31 grubba Exp $");
+RCSID("$Id: charsetmod.c,v 1.12 1999/04/27 01:45:03 marcus Exp $");
 #include "program.h"
 #include "interpret.h"
 #include "stralloc.h"
@@ -32,6 +32,7 @@ static struct program *std_16bite_program = NULL;
 struct std_cs_stor { 
   struct string_builder strbuild;
   struct pike_string *retain, *replace;
+  struct svalue repcb;
 };
 
 struct std_rfc_stor {
@@ -70,7 +71,8 @@ static void f_create(INT32 args)
 {
   struct std_cs_stor *s = (struct std_cs_stor *)fp->current_storage;
 
-  check_all_args("create()", args, BIT_STRING|BIT_VOID|BIT_INT, 0);
+  check_all_args("create()", args, BIT_STRING|BIT_VOID|BIT_INT,
+		 BIT_FUNCTION|BIT_VOID|BIT_INT);
 
   if(args>0 && sp[-args].type == T_STRING) {
     if(s->replace != NULL)
@@ -78,10 +80,24 @@ static void f_create(INT32 args)
     add_ref(s->replace = sp[-args].u.string);
   }
 
+  if(args>1 && sp[1-args].type == T_FUNCTION)
+    assign_svalue(&s->repcb, &sp[1-args]);
+
   pop_n_elems(args);
   push_int(0);
 }
 
+static void f_set_repcb(INT32 args)
+{
+  struct std_cs_stor *s = (struct std_cs_stor *)fp->current_storage;
+
+  check_all_args("set_replacement_callback()", args,
+		 BIT_FUNCTION|BIT_INT, 0);
+
+  if(args>0)
+    assign_svalue(&s->repcb, &sp[-args]);
+}
+
 static void f_drain(INT32 args)
 {
   struct std_cs_stor *s = (struct std_cs_stor *)fp->current_storage;
@@ -372,7 +388,8 @@ static void f_rfc1345(INT32 args)
   p_wchar1 *tabl;
 
   check_all_args("rfc1345()", args, BIT_STRING, BIT_INT|BIT_VOID,
-		 BIT_STRING|BIT_VOID|BIT_INT, 0);
+		 BIT_STRING|BIT_VOID|BIT_INT, BIT_FUNCTION|BIT_VOID|BIT_INT,
+		 0);
 
   str = sp[-args].u.string;
 
@@ -399,8 +416,7 @@ static void f_rfc1345(INT32 args)
 	
 	if(hi2) {
 	  struct std16e_stor *s16;
-	  s16 = push_std_16bite((args>2 && sp[2-args].type==T_STRING?args-2:0),
-				args, lowtrans, 65536);
+	  s16 = push_std_16bite((args>2? args-2:0), args, lowtrans, 65536);
 	  
 	  s16->lowtrans = lowtrans;
 	  s16->lo = lowtrans;
@@ -415,8 +431,7 @@ static void f_rfc1345(INT32 args)
 	      }
 	} else {
 	  struct std8e_stor *s8;
-	  s8 = push_std_8bite((args>2 && sp[2-args].type==T_STRING? args-2:0),
-			      args, lowtrans, 65536);
+	  s8 = push_std_8bite((args>2? args-2:0), args, lowtrans, 65536);
 	  
 	  s8->lowtrans = lowtrans;
 	  s8->lo = lowtrans;
@@ -460,8 +475,7 @@ static void f_rfc1345(INT32 args)
       int i;
       unsigned int c;
 
-      s8 = push_std_8bite((args>2 && sp[2-args].type == T_STRING? args-2:0),
-			  args, lo, 65536);
+      s8 = push_std_8bite((args>2? args-2:0), args, lo, 65536);
       s8->lowtrans = lo;
       s8->lo = lo;
       s8->hi = lo;
@@ -1069,8 +1083,12 @@ void pike_module_init(void)
   ADD_FUNCTION("drain", f_drain,tFunc(,tStr), 0);
   /* function(:object) */
   ADD_FUNCTION("clear", f_clear,tFunc(,tObj), 0);
-  /* function(string|void:void) */
-  ADD_FUNCTION("create", f_create,tFunc(tOr(tStr,tVoid),tVoid), 0);
+  /* function(string|void,function(string:string)|void:void) */
+  ADD_FUNCTION("create", f_create,tFunc(tOr(tStr,tVoid) tOr(tFunc(tStr,tStr),tVoid),tVoid), 0);
+  /* function(function(string:string):void) */
+  ADD_FUNCTION("set_replacement_callback", f_set_repcb,tFunc(tFunc(tStr,tStr),tVoid), 0);
+  map_variable("_repcb", "function(string:string)", ID_STATIC,
+	       OFFSETOF(std_cs_stor, repcb), T_MIXED);
   set_init_callback(init_stor);
   set_exit_callback(exit_stor);
   std_cs_program = end_program();
@@ -1172,7 +1190,8 @@ void pike_module_init(void)
   std_8bit_program = end_program();
 
   add_function_constant("rfc1345", f_rfc1345,
-			"function(string,int|void,string|void:object)", 0);
+			"function(string,int|void,string|void,"
+			"function(string:string)|void:object)", 0);
 }
 
 void pike_module_exit(void)
diff --git a/src/modules/_Charset/iso2022.c b/src/modules/_Charset/iso2022.c
index 834c8670862efb106af3be2314e548d12685377f..c1d70b8f1f3a894cce0fde96312f2d8cc4a961d3 100644
--- a/src/modules/_Charset/iso2022.c
+++ b/src/modules/_Charset/iso2022.c
@@ -3,7 +3,7 @@
 #endif /* HAVE_CONFIG_H */
 
 #include "global.h"
-RCSID("$Id: iso2022.c,v 1.6 1999/03/07 01:22:04 grubba Exp $");
+RCSID("$Id: iso2022.c,v 1.7 1999/04/27 01:45:04 marcus Exp $");
 #include "program.h"
 #include "interpret.h"
 #include "stralloc.h"
@@ -36,6 +36,7 @@ struct iso2022enc_stor {
   struct gdesc g[2];
   struct pike_string *replace;
   struct string_builder strbuild;
+  struct svalue repcb;
 };
 
 #define EMIT(X) string_builder_putchar(&s->strbuild,(X))
@@ -583,7 +584,8 @@ static void f_create(INT32 args)
 {
   struct iso2022enc_stor *s = (struct iso2022enc_stor *)fp->current_storage;
 
-  check_all_args("create()", args, BIT_STRING|BIT_VOID|BIT_INT, 0);
+  check_all_args("create()", args, BIT_STRING|BIT_VOID|BIT_INT,
+		 BIT_FUNCTION|BIT_VOID|BIT_INT, 0);
 
   if(args>0 && sp[-args].type == T_STRING) {
     if(s->replace != NULL)
@@ -591,10 +593,24 @@ static void f_create(INT32 args)
     add_ref(s->replace = sp[-args].u.string);
   }
 
+  if(args>1 && sp[1-args].type == T_FUNCTION)
+    assign_svalue(&s->repcb, &sp[1-args]);
+
   pop_n_elems(args);
   push_int(0);
 }
 
+static void f_set_repcb(INT32 args)
+{
+  struct iso2022enc_stor *s = (struct iso2022enc_stor *)fp->current_storage;
+
+  check_all_args("set_replacement_callback()", args,
+		 BIT_FUNCTION|BIT_INT, 0);
+
+  if(args>0)
+    assign_svalue(&s->repcb, &sp[-args]);
+}
+
 static void init_stor(struct object *o)
 {
   struct iso2022_stor *s = (struct iso2022_stor *)fp->current_storage;
@@ -668,8 +684,12 @@ void iso2022_init(void)
   ADD_FUNCTION("drain", f_enc_drain,tFunc(,tStr), 0);
   /* function(:object) */
   ADD_FUNCTION("clear", f_enc_clear,tFunc(,tObj), 0);
-  /* function(string|void:void) */
-  ADD_FUNCTION("create", f_create,tFunc(tOr(tStr,tVoid),tVoid), 0);
+  /* function(string|void,function(string:string)|void:void) */
+  ADD_FUNCTION("create", f_create,tFunc(tOr(tStr,tVoid) tOr(tFunc(tStr,tStr),tVoid),tVoid), 0);
+  /* function(function(string:string):void) */
+  ADD_FUNCTION("set_replacement_callback", f_set_repcb,tFunc(tFunc(tStr,tStr),tVoid), 0);
+  map_variable("_repcb", "function(string:string)", ID_STATIC,
+	       OFFSETOF(iso2022enc_stor, repcb), T_MIXED);
   set_init_callback(init_enc_stor);
   set_exit_callback(exit_enc_stor);
   add_program_constant("ISO2022Enc", iso2022enc_program = end_program(),
diff --git a/src/modules/_Charset/module.pmod.in b/src/modules/_Charset/module.pmod.in
index c6c8d8f0669591e1c0e221c7bcd7035fb2b74f8d..75e8c42d4d253903f58126e62108149760a55103 100644
--- a/src/modules/_Charset/module.pmod.in
+++ b/src/modules/_Charset/module.pmod.in
@@ -47,7 +47,8 @@ object decoder(string name)
   throw(({"Unknown character encoding "+name+"\n", backtrace()}));
 }
 
-object encoder(string name, string|void replacement)
+object encoder(string name, string|void replacement,
+	       function(string:string)|void repcb)
 {
   if(!name || (<
     "iso_8859-1:1987", "iso-8859-1", "iso_8859-1", "iso-ir-100", "latin1",
@@ -57,12 +58,17 @@ object encoder(string name, string|void replacement)
     return class {
       static private string s = "";
       static private string|void replacement;
-      static private string low_convert(string s, string|void r)
+      static private function(string:string)|void repcb;
+      static private string low_convert(string s, string|void r,
+					function(string:string)|void rc)
       {
 	int i = strlen(s);
+	string rr;
 	while(--i>=0)
 	  if(s[i]>255)
-	    if(r)
+	    if(rc && (rr = rc(s[i..i])))
+	      s=s[..i-1]+low_convert(rr,r)+s[i+1..];
+	    else if(r)
 	      s=s[..i-1]+low_convert(r)+s[i+1..];
 	    else
 	      throw(({"Character unsupported by encoding.\n", backtrace()}));
@@ -70,7 +76,7 @@ object encoder(string name, string|void replacement)
       }
       object feed(string ss)
       {
-	s += low_convert(ss, replacement);
+	s += low_convert(ss, replacement, repcb);
 	return this_object();
       }
       string drain()
@@ -84,14 +90,19 @@ object encoder(string name, string|void replacement)
 	s = "";
 	return this_object();
       }
-      void create(string|void r)
+      void set_replacement_callback(function(string:string) rc)
+      {
+	repcb = rc;
+      }
+      void create(string|void r, string|void rc)
       {
 	replacement = r;
+	repcb = rc;
       }
-    }(replacement);
+    }(replacement, repcb);
 
   if(name[..7]=="iso-2022")
-    return ISO2022Enc(replacement);
+    return ISO2022Enc(replacement, repcb);
 
   program p = ([
     "utf-7": UTF7enc,
@@ -99,9 +110,9 @@ object encoder(string name, string|void replacement)
   ])[name];
 
   if(p)
-    return p(replacement);
+    return p(replacement, repcb);
 
-  object o = rfc1345(name, 1, replacement);
+  object o = rfc1345(name, 1, replacement, repcb);
 
   if(o)
     return o;