diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index d658df1e57229f05560545352f333b768b609a48..6f1bc1b66d881660a3b806109660f0a29cf317d4 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -38,11 +38,12 @@
 static backslashResult exec_command(const char *cmd,
 			 char *const * options,
 			 const char *options_string,
-			 PQExpBuffer query_buf);
+			 PQExpBuffer query_buf,
+			 int encoding);
 
 static bool do_edit(const char *filename_arg, PQExpBuffer query_buf);
 
-static char * unescape(const char *source);
+static char * unescape(const char *source, int encoding);
 
 static bool do_connect(const char *new_dbname,
                        const char *new_user);
@@ -79,7 +80,8 @@ static bool do_shell(const char *command);
 backslashResult
 HandleSlashCmds(const char *line,
 				PQExpBuffer query_buf,
-				const char **end_of_cmd)
+				const char **end_of_cmd,
+				int encoding)
 {
 	backslashResult status = CMD_SKIP_LINE;
 	char	   *my_line;
@@ -131,14 +133,14 @@ HandleSlashCmds(const char *line,
 																				 * whitespace */
 
 		i = 0;
-		token = strtokx(options_string, " \t", "\"'`", '\\', &quote, &pos);
+		token = strtokx(options_string, " \t", "\"'`", '\\', &quote, &pos, encoding);
 
 		for (i = 0; token && i < NR_OPTIONS; i++)
 		{
 			switch (quote)
 			{
 				case '"':
-					options[i] = unescape(token);
+					options[i] = unescape(token, encoding);
 					break;
 				case '\'':
 					options[i] = xstrdup(token);
@@ -147,7 +149,7 @@ HandleSlashCmds(const char *line,
 					{
 						bool		error = false;
 						FILE	   *fd = NULL;
-						char	   *file = unescape(token);
+						char	   *file = unescape(token, encoding);
 						PQExpBufferData output;
 						char		buf[512];
 						size_t		result;
@@ -217,14 +219,14 @@ HandleSlashCmds(const char *line,
 			if (continue_parse)
 				break;
 
-			token = strtokx(NULL, " \t", "\"'`", '\\', &quote, &pos);
+			token = strtokx(NULL, " \t", "\"'`", '\\', &quote, &pos, encoding);
 		} /* for */
 
         options[i] = NULL;
 	}
 
 	cmd = my_line;
-	status = exec_command(cmd, options, options_string, query_buf);
+	status = exec_command(cmd, options, options_string, query_buf, encoding);
 
 	if (status == CMD_UNKNOWN)
 	{
@@ -246,7 +248,7 @@ HandleSlashCmds(const char *line,
 		new_cmd[0] = cmd[0];
 		new_cmd[1] = '\0';
 
-		status = exec_command(new_cmd, (char *const *) new_options, my_line + 2, query_buf);
+		status = exec_command(new_cmd, (char *const *) new_options, my_line + 2, query_buf, encoding);
 	}
 
 	if (status == CMD_UNKNOWN)
@@ -283,7 +285,8 @@ static backslashResult
 exec_command(const char *cmd,
 			 char *const * options,
 			 const char *options_string,
-			 PQExpBuffer query_buf)
+			 PQExpBuffer query_buf,
+			 int encoding)
 {
 	bool		success = true; /* indicate here if the command ran ok or
 								 * failed */
@@ -338,7 +341,7 @@ exec_command(const char *cmd,
 
 	/* \copy */
 	else if (strcasecmp(cmd, "copy") == 0)
-		success = do_copy(options_string);
+		success = do_copy(options_string, encoding);
 
 	/* \copyright */
 	else if (strcmp(cmd, "copyright") == 0)
@@ -465,7 +468,7 @@ exec_command(const char *cmd,
 			success = false;
 		}
 		else
-			success = process_file(options[0]);
+			success = process_file(options[0], encoding);
 	}
 
 
@@ -768,7 +771,7 @@ exec_command(const char *cmd,
  * The return value is malloc()'ed.
  */
 static char *
-unescape(const char *source)
+unescape(const char *source, int encoding)
 {
 	unsigned char *p;
 	bool		esc = false;	/* Last character we saw was the escape
@@ -790,7 +793,7 @@ unescape(const char *source)
 		exit(EXIT_FAILURE);
 	}
 
-	for (p = (char *) source; *p; p += PQmblen(p))
+	for (p = (char *) source; *p; p += PQmblen(p, encoding))
 	{
 		if (esc)
 		{
@@ -1219,7 +1222,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
  * Handler for \i, but can be used for other things as well.
  */
 bool
-process_file(const char *filename)
+process_file(const char *filename, int encoding)
 {
 	FILE	   *fd;
 	int			result;
@@ -1241,7 +1244,7 @@ process_file(const char *filename)
 		return false;
 	}
 
-	result = MainLoop(fd);
+	result = MainLoop(fd, encoding);
 	fclose(fd);
 	return (result == EXIT_SUCCESS);
 }
diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h
index a8cc220e7c939c9e1e9332c71951dd8d45d0f085..5543cbe9c2d055f693a3cf010e54762c01d668ed 100644
--- a/src/bin/psql/command.h
+++ b/src/bin/psql/command.h
@@ -27,10 +27,10 @@ typedef enum _backslashResult
 backslashResult
 HandleSlashCmds(const char *line,
 				PQExpBuffer query_buf,
-				const char **end_of_cmd);
+				const char **end_of_cmd, int encoding);
 
 bool
-process_file(const char *filename);
+process_file(const char *filename, int encoding);
 
 bool
 do_pset(const char *param,
diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c
index 66449873346100029b02b0b0fdcb477044f5a192..8e64c80b98272bf7fbcb55835c21b39f5869b4eb 100644
--- a/src/bin/psql/copy.c
+++ b/src/bin/psql/copy.c
@@ -58,7 +58,7 @@ free_copy_options(struct copy_options * ptr)
 
 
 static struct copy_options *
-parse_slash_copy(const char *args)
+parse_slash_copy(const char *args, int encoding)
 {
 	struct copy_options *result;
 	char	   *line;
@@ -74,7 +74,7 @@ parse_slash_copy(const char *args)
 		exit(EXIT_FAILURE);
 	}
 
-	token = strtokx(line, " \t", "\"", '\\', &quote, NULL);
+	token = strtokx(line, " \t", "\"", '\\', &quote, NULL, encoding);
 	if (!token)
 		error = true;
 	else
@@ -84,7 +84,7 @@ parse_slash_copy(const char *args)
         if (!quote && strcasecmp(token, "binary") == 0)
 		{
 			result->binary = true;
-			token = strtokx(NULL, " \t", "\"", '\\', &quote, NULL);
+			token = strtokx(NULL, " \t", "\"", '\\', &quote, NULL, encoding);
 			if (!token)
 				error = true;
 		}
@@ -99,14 +99,14 @@ parse_slash_copy(const char *args)
 
 	if (!error)
 	{
-		token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
+		token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
 		if (!token)
 			error = true;
 		else
 		{
 			if (strcasecmp(token, "with") == 0)
 			{
-				token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
+				token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
 				if (!token || strcasecmp(token, "oids") != 0)
 					error = true;
 				else
@@ -114,7 +114,7 @@ parse_slash_copy(const char *args)
 
 				if (!error)
 				{
-					token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
+					token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
 					if (!token)
 						error = true;
 				}
@@ -131,7 +131,7 @@ parse_slash_copy(const char *args)
 
 	if (!error)
 	{
-		token = strtokx(NULL, " \t", "'", '\\', &quote, NULL);
+		token = strtokx(NULL, " \t", "'", '\\', &quote, NULL, encoding);
 		if (!token)
 			error = true;
 		else if (!quote && (strcasecmp(token, "stdin")==0 || strcasecmp(token, "stdout")==0))
@@ -142,21 +142,21 @@ parse_slash_copy(const char *args)
 
 	if (!error)
 	{
-		token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
+		token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
 		if (token)
 		{
 			if (strcasecmp(token, "using") == 0)
 			{
-				token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
+				token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
 				if (!token || strcasecmp(token, "delimiters") != 0)
 					error = true;
 				else
 				{
-					token = strtokx(NULL, " \t", "'", '\\', NULL, NULL);
+					token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, encoding);
 					if (token)
                     {
 						result->delim = xstrdup(token);
-                        token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
+                        token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
                     }
 					else
 						error = true;
@@ -167,17 +167,17 @@ parse_slash_copy(const char *args)
             {
                 if (strcasecmp(token, "with") == 0)
                 {
-                    token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
+                    token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
                     if (!token || strcasecmp(token, "null") != 0)
                         error = true;
                     else
                     {
-                        token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL);
+                        token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, encoding);
                         if (!token || strcasecmp(token, "as") != 0)
                             error = true;
                         else
                         {
-                            token = strtokx(NULL, " \t", "'", '\\', NULL, NULL);
+                            token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, encoding);
                             if (token)
                                 result->null = xstrdup(token);
                         }
@@ -214,7 +214,7 @@ parse_slash_copy(const char *args)
  * file or route its response into the file.
  */
 bool
-do_copy(const char *args)
+do_copy(const char *args, int encoding)
 {
 	char		query[128 + NAMEDATALEN];
 	FILE	   *copystream;
@@ -223,7 +223,7 @@ do_copy(const char *args)
 	bool		success;
 
 	/* parse options */
-	options = parse_slash_copy(args);
+	options = parse_slash_copy(args, encoding);
 
 	if (!options)
 		return false;
diff --git a/src/bin/psql/copy.h b/src/bin/psql/copy.h
index 840fb27fe12c8c2e843cf2f705d95896500c7198..6258fcb2806dbce369443c38424e79a9400a6d01 100644
--- a/src/bin/psql/copy.h
+++ b/src/bin/psql/copy.h
@@ -8,7 +8,7 @@
 
 /* handler for \copy */
 bool
-			do_copy(const char *args);
+			do_copy(const char *args, int encoding);
 
 
 /* lower level processors for copy in/out streams */
diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c
index 919025cb5c467bc9faa42c98d37dde461a141812..6380b674fdc91fbdea8288348b6a8ab48f94ce64 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -25,7 +25,7 @@
  * FIXME: rewrite this whole thing with flex
  */
 int
-MainLoop(FILE *source)
+MainLoop(FILE *source, int encoding)
 {
 	PQExpBuffer query_buf;		/* buffer for query being accumulated */
     PQExpBuffer previous_buf;   /* if there isn't anything in the new buffer
@@ -212,10 +212,10 @@ MainLoop(FILE *source)
 		 * The current character is at line[i], the prior character at line[i
 		 * - prevlen], the next character at line[i + thislen].
 		 */
-#define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i))
+#define ADVANCE_1 (prevlen = thislen, i += thislen, thislen = PQmblen(line+i, encoding))
 
 		success = true;
-		for (i = 0, prevlen = 0, thislen = (len > 0) ? PQmblen(line) : 0;
+		for (i = 0, prevlen = 0, thislen = (len > 0) ? PQmblen(line, encoding) : 0;
              i < len;
              ADVANCE_1)
 		{
@@ -373,7 +373,7 @@ MainLoop(FILE *source)
                 /* handle backslash command */
                 slashCmdStatus = HandleSlashCmds(&line[i], 
                                                  query_buf->len>0 ? query_buf : previous_buf,
-                                                 &end_of_cmd);
+                                                 &end_of_cmd, encoding);
 
 				success = slashCmdStatus != CMD_ERROR;
 
diff --git a/src/bin/psql/mainloop.h b/src/bin/psql/mainloop.h
index 439703d04040a29c7e2db8d95c13567283889ef9..f76db73328e4aa971f82bb2f96fce0bfaa05d436 100644
--- a/src/bin/psql/mainloop.h
+++ b/src/bin/psql/mainloop.h
@@ -3,6 +3,6 @@
 
 #include <stdio.h>
 
-int MainLoop(FILE *source);
+int MainLoop(FILE *source, int encoding);
 
 #endif	 /* MAINLOOP_H */
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 2599a42199a6b9b7bfdceb0b9f637290f6b7b113..273a7e11ec51f5b6edb8e24d7aa4ed4e46263096 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -190,10 +190,10 @@ main(int argc, char **argv)
 
 	/* process file given by -f */
 	if (options.action == ACT_FILE)
-		successResult = process_file(options.action_string) ? 0 : 1;
+		successResult = process_file(options.action_string, PQclientencoding(pset.db)) ? 0 : 1;
 	/* process slash command if one was given to -c */
 	else if (options.action == ACT_SINGLE_SLASH)
-		successResult = HandleSlashCmds(options.action_string, NULL, NULL) != CMD_ERROR ? 0 : 1;
+		successResult = HandleSlashCmds(options.action_string, NULL, NULL, PQclientencoding(pset.db)) != CMD_ERROR ? 0 : 1;
 	/* If the query given to -c was a normal one, send it */
 	else if (options.action == ACT_SINGLE_QUERY)
 		successResult = SendQuery( options.action_string) ? 0 : 1;
@@ -202,7 +202,7 @@ main(int argc, char **argv)
     {
         process_psqlrc();
         initializeInput(options.no_readline ? 0 : 1);
-		successResult = MainLoop(stdin);
+		successResult = MainLoop(stdin, PQclientencoding(pset.db));
         finishInput();
     }
 
@@ -465,16 +465,20 @@ process_psqlrc(void)
 {
 	char	   *psqlrc;
 	char	   *home;
+	int	   encoding;
 
 #ifdef WIN32
 #define R_OK 0
 #endif
 
+	/* get client side encoding from envrionment variable if any */
+	encoding = PQenv2encoding();
+
 	/* System-wide startup file */
 	if (access("/etc/psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION, R_OK) == 0)
-		process_file("/etc/psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION);
+		process_file("/etc/psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION, encoding);
 	else if (access("/etc/psqlrc", R_OK) == 0)
-		process_file("/etc/psqlrc");
+		process_file("/etc/psqlrc", encoding);
 
 	/* Look for one in the home dir */
 	home = getenv("HOME");
@@ -490,12 +494,12 @@ process_psqlrc(void)
 
 		sprintf(psqlrc, "%s/.psqlrc-" PG_RELEASE "." PG_VERSION "." PG_SUBVERSION, home);
 		if (access(psqlrc, R_OK) == 0)
-			process_file(psqlrc);
+			process_file(psqlrc, encoding);
 		else
 		{
 			sprintf(psqlrc, "%s/.psqlrc", home);
 			if (access(psqlrc, R_OK) == 0)
-				process_file(psqlrc);
+				process_file(psqlrc, encoding);
 		}
 		free(psqlrc);
 	}
diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c
index 8473fd13944e7e85301410e161ede32d46680bcc..1421cf13608812d06877c46c60246755b596bb00 100644
--- a/src/bin/psql/stringutils.c
+++ b/src/bin/psql/stringutils.c
@@ -41,7 +41,8 @@ strtokx(const char *s,
 		const char *quote,
 		char escape,
 		char *was_quoted,
-		unsigned int *token_pos)
+		unsigned int *token_pos,
+		int encoding)
 {
 	static char *storage = NULL;/* store the local copy of the users
 								 * string here */
@@ -93,7 +94,7 @@ strtokx(const char *s,
 		for (p = start;
 			 *p && (*p != *cp || *(p - 1) == escape);
 #ifdef MULTIBYTE
-			 p += PQmblen(p)
+			 p += PQmblen(p, encoding)
 #else
 			 p++
 #endif
diff --git a/src/bin/psql/stringutils.h b/src/bin/psql/stringutils.h
index 5d72006c8ed98b62154664b68363956851cc3c5e..c9a161d88ed0996c3be48eebe89985b8648f6b8f 100644
--- a/src/bin/psql/stringutils.h
+++ b/src/bin/psql/stringutils.h
@@ -8,6 +8,7 @@ extern char *strtokx(const char *s,
 		const char *quote,
 		char escape,
 		char *was_quoted,
-		unsigned int *token_pos);
+		unsigned int *token_pos,
+		int encoding);
 
 #endif	 /* STRINGUTILS_H */