aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1998-02-24 15:27:04 +0000
committerMarc G. Fournier <scrappy@hub.org>1998-02-24 15:27:04 +0000
commit0227a4e1141ae83ac3ae145fa283ede13e86e23e (patch)
tree587d06ca0b71c88ae2c1ac4a90bd5bba13a5c668
parent96316211c3a1300b304d452e09c726fb775aa502 (diff)
downloadpostgresql-0227a4e1141ae83ac3ae145fa283ede13e86e23e.tar.gz
postgresql-0227a4e1141ae83ac3ae145fa283ede13e86e23e.zip
From: "Denis V. Dmitrienko" <denis@null.net>
What it does: It solves stupid problem with cyrillic charsets IP-based on-fly recoding. take a look at /data/charset.conf for details. You can use any tables for any charset. Tables are from Russian Apache project. Tables in this patch contains also Ukrainian characters. Then run ./configure --enable-recode
-rw-r--r--src/backend/libpq/hba.c188
-rw-r--r--src/backend/postmaster/postmaster.c22
-rw-r--r--src/backend/tcop/postgres.c8
-rw-r--r--src/backend/utils/adt/varchar.c25
-rw-r--r--src/backend/utils/adt/varlena.c12
-rw-r--r--src/backend/utils/init/miscinit.c146
-rw-r--r--src/configure.in21
-rw-r--r--src/data/charset.conf40
-rw-r--r--src/data/charset.conf.orig0
-rw-r--r--src/data/koi-alt.tab85
-rw-r--r--src/data/koi-alt.tab.orig0
-rw-r--r--src/data/koi-iso.tab75
-rw-r--r--src/data/koi-iso.tab.orig0
-rw-r--r--src/data/koi-koi.tab2
-rw-r--r--src/data/koi-koi.tab.orig0
-rw-r--r--src/data/koi-mac.tab130
-rw-r--r--src/data/koi-mac.tab.orig0
-rw-r--r--src/data/koi-win.tab85
-rw-r--r--src/data/koi-win.tab.orig0
-rw-r--r--src/include/config.h.in3
-rw-r--r--src/include/postgres.h10
21 files changed, 844 insertions, 8 deletions
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 857f324a0e7..872601293c7 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.27 1998/01/27 03:24:56 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.28 1998/02/24 15:18:41 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -846,6 +846,192 @@ authident(struct sockaddr_in *raddr, struct sockaddr_in *laddr,
}
+#ifdef CYR_RECODE
+#define CHARSET_FILE "charset.conf"
+#define MAX_CHARSETS 10
+#define KEY_HOST 1
+#define KEY_BASE 2
+#define KEY_TABLE 3
+
+struct CharsetItem
+{
+ char Orig[MAX_TOKEN];
+ char Dest[MAX_TOKEN];
+ char Table[MAX_TOKEN];
+};
+
+int InRange(char *buf,int host)
+{
+ int valid,i,FromAddr,ToAddr,tmp;
+ struct in_addr file_ip_addr;
+ char *p;
+ unsigned int one=0x80000000,NetMask=0;
+ unsigned char mask;
+ p = strchr(buf,'/');
+ if(p)
+ {
+ *p++ = '\0';
+ valid = inet_aton(buf, &file_ip_addr);
+ if(valid)
+ {
+ mask = strtoul(p,0,0);
+ FromAddr = ntohl(file_ip_addr.s_addr);
+ ToAddr = ntohl(file_ip_addr.s_addr);
+ for(i=0;i<mask;i++)
+ {
+ NetMask |= one;
+ one >>= 1;
+ }
+ FromAddr &= NetMask;
+ ToAddr = ToAddr | ~NetMask;
+ tmp = ntohl(host);
+ return ((unsigned)tmp>=(unsigned)FromAddr &&
+ (unsigned)tmp<=(unsigned)ToAddr);
+ }
+ }
+ else
+ {
+ p = strchr(buf,'-');
+ if(p)
+ {
+ *p++ = '\0';
+ valid = inet_aton(buf, &file_ip_addr);
+ if(valid)
+ {
+ FromAddr = ntohl(file_ip_addr.s_addr);
+ valid = inet_aton(p, &file_ip_addr);
+ if(valid)
+ {
+ ToAddr = ntohl(file_ip_addr.s_addr);
+ tmp = ntohl(host);
+ return ((unsigned)tmp>=(unsigned)FromAddr &&
+ (unsigned)tmp<=(unsigned)ToAddr);
+ }
+ }
+ }
+ else
+ {
+ valid = inet_aton(buf, &file_ip_addr);
+ if(valid)
+ {
+ FromAddr = file_ip_addr.s_addr;
+ return ((unsigned)FromAddr == (unsigned)host);
+ }
+ }
+ }
+ return false;
+}
+
+void GetCharSetByHost(char TableName[],int host, const char DataDir[])
+{
+ FILE *file;
+ char buf[MAX_TOKEN],BaseCharset[MAX_TOKEN],
+ OrigCharset[MAX_TOKEN],DestCharset[MAX_TOKEN],HostCharset[MAX_TOKEN];
+ char c,eof=false;
+ char *map_file;
+ int key=0,i;
+ struct CharsetItem* ChArray[MAX_CHARSETS];
+ int ChIndex=0;
+
+ *TableName = '\0';
+ map_file = (char *) malloc((strlen(DataDir) +
+ strlen(CHARSET_FILE)+2)*sizeof(char));
+ sprintf(map_file, "%s/%s", DataDir, CHARSET_FILE);
+ file = fopen(map_file, "r");
+ if (file == NULL)
+ return;
+ while (!eof)
+ {
+ c = getc(file);
+ ungetc(c, file);
+ if (c == EOF)
+ eof = true;
+ else
+ {
+ if (c == '#')
+ read_through_eol(file);
+ else
+ {
+ /* Read the key */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ if (strcasecmp(buf, "HostCharset") == 0)
+ key = KEY_HOST;
+ if (strcasecmp(buf, "BaseCharset") == 0)
+ key = KEY_BASE;
+ if (strcasecmp(buf, "RecodeTable") == 0)
+ key = KEY_TABLE;
+ switch(key)
+ {
+ case KEY_HOST:
+ /* Read the host */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ if (InRange(buf,host))
+ {
+ /* Read the charset */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ strcpy(HostCharset,buf);
+ }
+ }
+ }
+ break;
+ case KEY_BASE:
+ /* Read the base charset */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ strcpy(BaseCharset,buf);
+ }
+ break;
+ case KEY_TABLE:
+ /* Read the original charset */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ strcpy(OrigCharset,buf);
+ /* Read the destination charset */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ strcpy(DestCharset,buf);
+ /* Read the table filename */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ ChArray[ChIndex] = (struct CharsetItem *) malloc(sizeof(struct CharsetItem));
+ strcpy(ChArray[ChIndex]->Orig,OrigCharset);
+ strcpy(ChArray[ChIndex]->Dest,DestCharset);
+ strcpy(ChArray[ChIndex]->Table,buf);
+ ChIndex++;
+ }
+ }
+ }
+ break;
+ }
+ read_through_eol(file);
+ }
+ }
+ }
+ }
+ fclose(file);
+ free(map_file);
+
+ for(i=0; i<ChIndex; i++)
+ {
+ if(!strcasecmp(BaseCharset,ChArray[i]->Orig) &&
+ !strcasecmp(HostCharset,ChArray[i]->Dest))
+ {
+ strncpy(TableName,ChArray[i]->Table,79);
+ }
+ free((struct CharsetItem *) ChArray[i]);
+ }
+}
+#endif
extern int
hba_getauthmethod(SockAddr *raddr, char *database, char *auth_arg,
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 5f966532c42..255fe2df352 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.73 1998/01/31 20:14:15 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.74 1998/02/24 15:19:00 scrappy Exp $
*
* NOTES
*
@@ -203,6 +203,10 @@ static void readStartupPacket(char *arg, PacketLen len, char *pkt);
static int initMasks(fd_set *rmask, fd_set *wmask);
static void RandomSalt(char* salt);
+#ifdef CYR_RECODE
+void GetCharSetByHost(char *,int,char *);
+#endif
+
extern char *optarg;
extern int optind,
opterr;
@@ -974,7 +978,14 @@ BackendStartup(Port *port)
Backend *bn; /* for backend cleanup */
int pid,
i;
+
+#ifdef CYR_RECODE
+#define NR_ENVIRONMENT_VBL 6
+char ChTable[80];
+#else
#define NR_ENVIRONMENT_VBL 5
+#endif
+
static char envEntry[NR_ENVIRONMENT_VBL][2 * ARGV_SIZE];
for (i = 0; i < NR_ENVIRONMENT_VBL; ++i)
@@ -1000,6 +1011,15 @@ BackendStartup(Port *port)
sprintf(envEntry[4], "IPC_KEY=%d", ipc_key);
putenv(envEntry[4]);
+#ifdef CYR_RECODE
+ GetCharSetByHost(ChTable,port->raddr.in.sin_addr.s_addr,DataDir);
+ if(*ChTable != '\0')
+ {
+ sprintf(envEntry[5], "PG_RECODETABLE=%s", ChTable);
+ putenv(envEntry[5]);
+ }
+#endif
+
if (DebugLvl > 2)
{
char **p;
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 3575d69d4f5..b981dcb125a 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.65 1998/02/02 00:05:03 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.66 1998/02/24 15:19:23 scrappy Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -1168,6 +1168,10 @@ PostgresMain(int argc, char *argv[])
SetPgUserName();
userName = GetPgUserName();
+#ifdef CYR_RECODE
+ SetCharSet();
+#endif
+
if (FindBackend(pg_pathname, argv[0]) < 0)
elog(FATAL, "%s: could not locate executable, bailing out...",
argv[0]);
@@ -1293,7 +1297,7 @@ PostgresMain(int argc, char *argv[])
if (IsUnderPostmaster == false)
{
puts("\nPOSTGRES backend interactive interface");
- puts("$Revision: 1.65 $ $Date: 1998/02/02 00:05:03 $");
+ puts("$Revision: 1.66 $ $Date: 1998/02/24 15:19:23 $");
}
/* ----------------
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index a7b6abdaeb1..f3a2df7b94d 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.27 1998/02/10 16:03:46 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.28 1998/02/24 15:19:44 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,6 +16,10 @@
#include "postgres.h"
#include "utils/builtins.h"
+#ifdef CYR_RECODE
+char *convertstr(char *,int,int);
+#endif
+
/*
* CHAR() and VARCHAR() types are part of the ANSI SQL standard. CHAR()
* is for blank-padded string whose length is specified in CREATE TABLE.
@@ -84,6 +88,11 @@ bpcharin(char *s, int dummy, int16 atttypmod)
if (*r == '\0')
break;
}
+
+#ifdef CYR_RECODE
+ convertstr(result + VARHDRSZ,len,0);
+#endif
+
/* blank pad the string if necessary */
for (; i < len; i++)
{
@@ -110,6 +119,11 @@ bpcharout(char *s)
result = (char *) palloc(len + 1);
StrNCpy(result, VARDATA(s), len+1); /* these are blank-padded */
}
+
+#ifdef CYR_RECODE
+ convertstr(result,len,1);
+#endif
+
return (result);
}
@@ -143,6 +157,10 @@ varcharin(char *s, int dummy, int16 atttypmod)
VARSIZE(result) = len;
strncpy(VARDATA(result), s, len - VARHDRSZ);
+#ifdef CYR_RECODE
+ convertstr(result + VARHDRSZ,len,0);
+#endif
+
return (result);
}
@@ -164,6 +182,11 @@ varcharout(char *s)
result = (char *) palloc(len + 1);
StrNCpy(result, VARDATA(s), len+1);
}
+
+#ifdef CYR_RECODE
+ convertstr(result,len,1);
+#endif
+
return (result);
}
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 1fc611286c5..8d334a2ffd9 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.29 1998/01/07 18:46:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.30 1998/02/24 15:19:45 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -157,6 +157,11 @@ textin(char *inputText)
VARSIZE(result) = len;
memmove(VARDATA(result), inputText, len - VARHDRSZ);
+
+#ifdef CYR_RECODE
+ convertstr(VARDATA(result),len-VARHDRSZ,0);
+#endif
+
return (result);
}
@@ -180,6 +185,11 @@ textout(text *vlena)
result = (char *) palloc(len + 1);
memmove(result, VARDATA(vlena), len);
result[len] = '\0';
+
+#ifdef CYR_RECODE
+ convertstr(result,len,1);
+#endif
+
return (result);
}
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index fe26cdde864..9bc13907dc2 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.9 1998/01/25 04:07:00 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.10 1998/02/24 15:20:16 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -51,6 +51,11 @@ extern char *DatabaseName;
extern char *UserName;
extern char *DatabasePath;
+#ifdef CYR_RECODE
+unsigned char RecodeForwTable[128];
+unsigned char RecodeBackTable[128];
+#endif
+
/*
* Define USE_ENVIRONMENT to get PGDATA, etc. from environment variables.
@@ -258,6 +263,145 @@ SetDatabaseName(char *name)
strcpy(DatabaseName, name);
}
+#ifdef CYR_RECODE
+#define MAX_TOKEN 80
+
+/* Some standard C libraries, including GNU, have an isblank() function.
+ Others, including Solaris, do not. So we have our own.
+*/
+static bool
+isblank(const char c)
+{
+ return (c == ' ' || c == 9 /* tab */ );
+}
+
+static void
+next_token(FILE *fp, char *buf, const int bufsz)
+{
+/*--------------------------------------------------------------------------
+ Grab one token out of fp. Tokens are strings of non-blank
+ characters bounded by blank characters, beginning of line, and end
+ of line. Blank means space or tab. Return the token as *buf.
+ Leave file positioned to character immediately after the token or
+ EOF, whichever comes first. If no more tokens on line, return null
+ string as *buf and position file to beginning of next line or EOF,
+ whichever comes first.
+--------------------------------------------------------------------------*/
+ int c;
+ char *eb = buf + (bufsz - 1);
+
+ /* Move over inital token-delimiting blanks */
+ while (isblank(c = getc(fp)));
+
+ if (c != '\n')
+ {
+
+ /*
+ * build a token in buf of next characters up to EOF, eol, or
+ * blank.
+ */
+ while (c != EOF && c != '\n' && !isblank(c))
+ {
+ if (buf < eb)
+ *buf++ = c;
+ c = getc(fp);
+
+ /*
+ * Put back the char right after the token (putting back EOF
+ * is ok)
+ */
+ }
+ ungetc(c, fp);
+ }
+ *buf = '\0';
+}
+
+static void
+read_through_eol(FILE *file)
+{
+ int c;
+
+ do
+ c = getc(file);
+ while (c != '\n' && c != EOF);
+}
+
+void SetCharSet()
+{
+ FILE *file;
+ char *p,c,eof=false;
+ char *map_file;
+ char buf[MAX_TOKEN];
+ int i;
+ unsigned char FromChar,ToChar;
+
+ for(i=0; i<128; i++)
+ {
+ RecodeForwTable[i] = i+128;
+ RecodeBackTable[i] = i+128;
+ }
+
+ p = getenv("PG_RECODETABLE");
+ if (p && *p != '\0')
+ {
+ map_file = (char *) malloc((strlen(DataDir) +
+ strlen(p)+2)*sizeof(char));
+ sprintf(map_file, "%s/%s", DataDir, p);
+ file = fopen(map_file, "r");
+ if (file == NULL)
+ return;
+ eof=false;
+ while (!eof)
+ {
+ c = getc(file);
+ ungetc(c, file);
+ if (c == EOF)
+ eof = true;
+ else
+ {
+ if (c == '#')
+ read_through_eol(file);
+ else
+ {
+ /* Read the FromChar */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ FromChar = strtoul(buf,0,0);
+ /* Read the ToChar */
+ next_token(file, buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ ToChar = strtoul(buf,0,0);
+ RecodeForwTable[FromChar-128] = ToChar;
+ RecodeBackTable[ToChar-128] = FromChar;
+ }
+ read_through_eol(file);
+ }
+ }
+ }
+ }
+ fclose(file);
+ free(map_file);
+ }
+}
+
+char* convertstr(unsigned char *buff,int len,int dest)
+{
+ int i;
+ char *ch=buff;
+ for (i = 0; i < len; i++,buff++)
+ {
+ if (*buff >127)
+ if (dest)
+ *buff = RecodeForwTable[*buff-128];
+ else
+ *buff = RecodeBackTable[*buff-128];
+ }
+ return ch;
+}
+#endif
+
/* ----------------
* GetPgUserName and SetPgUserName
*
diff --git a/src/configure.in b/src/configure.in
index 5553f771016..a0fd5f35980 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -211,6 +211,19 @@ else
fi
export USE_LOCALE
+dnl We exclude cyrillic recode support unless we override it with
+dnl --enable-recode
+dnl --disable-recode to explicitly disable it
+dnl --enable-recode to explicitly enable it
+dnl It defaults to disabled
+if test "$enable_recode" = "yes" -o "$enable_recode" = "no"
+then
+ CYR_RECODE=$enable_recode
+else
+ CYR_RECODE=no
+fi
+export CYR_RECODE
+
dnl We use the default value of 5432 for the DEF_PGPORT value. If
dnl we over-ride it with --with-pgport=port then we bypass this piece
if test "X$with_pgport" != "X"
@@ -518,6 +531,14 @@ then
else
AC_MSG_RESULT(disabled)
fi
+AC_MSG_CHECKING(setting CYR_RECODE)
+if test "$CYR_RECODE" = "yes"
+then
+ AC_MSG_RESULT(enabled)
+ AC_DEFINE(CYR_RECODE)
+else
+ AC_MSG_RESULT(disabled)
+fi
AC_MSG_CHECKING(setting DEF_PGPORT)
AC_DEFINE_UNQUOTED(DEF_PGPORT, "${DEF_PGPORT}")
AC_MSG_RESULT($DEF_PGPORT)
diff --git a/src/data/charset.conf b/src/data/charset.conf
new file mode 100644
index 00000000000..f1be4c57fc9
--- /dev/null
+++ b/src/data/charset.conf
@@ -0,0 +1,40 @@
+#
+# Example PostgreSQL charsets control file.
+#
+# Should be placed in $PG_DATA directory.
+#
+# On the fly recoding charsets, based on client's IP address.
+# For example: koi8-u (koi) <-> cp1251 (win) <-> cp866 (alt)
+#
+
+# Base charset for backend
+# Most Unices use koi8-r(u) as base charset. But Solaris
+# use iso8859-5 and some networkless workstations use cp866.
+BaseCharset koi
+
+# There are recode table definitions from base charset to
+# other. Table names are relative to $PG_DATA directory.
+# Tables are taken from Russian Apache <http://apache.lexa.ru>.
+RecodeTable koi alt koi-alt.tab
+RecodeTable koi win koi-win.tab
+RecodeTable koi iso koi-iso.tab
+RecodeTable koi koi koi-koi.tab
+RecodeTable alt win othertabs/alt-win.tab
+RecodeTable alt koi othertabs/alt-koi.tab
+RecodeTable iso koi othertabs/iso-koi.tab
+
+# Local loopback
+HostCharset 127.0.0.1 koi
+
+# Yet another Unix (maybe ;)
+HostCharset 192.168.0.1 koi
+
+# There are Windows on 192.168.1.64 through 192.168.1.95
+HostCharset 192.168.1.64/27 win
+
+# There are cp866 (alt) systems on 192.168.2.3 through
+# 192.168.2.7 (exept 192.168.2.4 - see below)
+HostCharset 192.168.2.3-192.168.2.7 alt
+
+# This is exeption from previous rule!
+HostCharset 192.168.2.4 win
diff --git a/src/data/charset.conf.orig b/src/data/charset.conf.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/data/charset.conf.orig
diff --git a/src/data/koi-alt.tab b/src/data/koi-alt.tab
new file mode 100644
index 00000000000..2f70efdda86
--- /dev/null
+++ b/src/data/koi-alt.tab
@@ -0,0 +1,85 @@
+# Line with '#' at the begin is comment
+# table file may contain number of line as you wana
+# first - code of symbol, second translate code of symbol
+# codes may be in two forms: decimal and hex
+# examples:
+# 192 225
+# 0x81 226
+# 226 0x81
+# 0x90 0xfe
+# patch for Russia by Dm.Kryukov (dvk@stack.serpukhov.su)
+#
+163 241
+164 243
+166 249
+167 245
+173 173
+179 240
+180 242
+182 248
+183 244
+189 189
+192 238
+193 160
+194 161
+195 230
+196 164
+197 165
+198 228
+199 163
+200 229
+201 168
+202 169
+203 170
+204 171
+205 172
+206 173
+207 174
+208 175
+209 239
+210 224
+211 225
+212 226
+213 227
+214 166
+215 162
+216 236
+217 235
+218 167
+219 232
+220 237
+221 233
+222 231
+223 234
+224 158
+225 128
+226 129
+227 150
+228 132
+229 133
+230 148
+231 131
+232 149
+233 136
+234 137
+235 138
+236 139
+237 140
+238 141
+239 142
+240 143
+241 159
+242 144
+243 145
+244 146
+245 147
+246 134
+247 130
+248 156
+249 155
+250 135
+251 152
+252 157
+253 153
+254 151
+255 154
diff --git a/src/data/koi-alt.tab.orig b/src/data/koi-alt.tab.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/data/koi-alt.tab.orig
diff --git a/src/data/koi-iso.tab b/src/data/koi-iso.tab
new file mode 100644
index 00000000000..98dd1d9d092
--- /dev/null
+++ b/src/data/koi-iso.tab
@@ -0,0 +1,75 @@
+# Line with '#' at the begin is comment
+# table file may contain number of line as you wana
+# first - code of symbol, second translate code of symbol
+# codes may be in two forms: decimal and hex
+# examples:
+# 192 225
+# 0x81 226
+# 226 0x81
+# 0x90 0xfe
+# patch for Russia by Dm.Kryukov (dvk@stack.serpukhov.su)
+#
+192 0xee
+193 0xd0
+194 0xd1
+195 0xe6
+196 0xd4
+197 0xd5
+198 0xe4
+199 0xd3
+200 0xe5
+201 0xd8
+202 0xd9
+203 0xda
+204 0xdb
+205 0xdc
+206 0xdd
+207 0xde
+208 0xdf
+209 0xef
+210 0xe0
+211 0xe1
+212 0xe2
+213 0xe3
+214 0xd6
+215 0xd2
+216 0xec
+217 0xeb
+218 0xd7
+219 0xe8
+220 0xed
+221 0xe9
+222 0xe7
+223 0xea
+224 0xce
+225 0xb0
+226 0xb1
+227 0xc6
+228 0xb4
+229 0xb5
+230 0xc4
+231 0xb3
+232 0xc5
+233 0xb8
+234 0xb9
+235 0xba
+236 0xbb
+237 0xbc
+238 0xbd
+239 0xbe
+240 0xbf
+241 0xcf
+242 0xc0
+243 0xc1
+244 0xc2
+245 0xc3
+246 0xb6
+247 0xb2
+248 0xcc
+249 0xcb
+250 0xb7
+251 0xc8
+252 0xcd
+253 0xc9
+254 0xc7
+255 0xca
diff --git a/src/data/koi-iso.tab.orig b/src/data/koi-iso.tab.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/data/koi-iso.tab.orig
diff --git a/src/data/koi-koi.tab b/src/data/koi-koi.tab
new file mode 100644
index 00000000000..91a9389ee97
--- /dev/null
+++ b/src/data/koi-koi.tab
@@ -0,0 +1,2 @@
+# Hmm ...
+#
diff --git a/src/data/koi-koi.tab.orig b/src/data/koi-koi.tab.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/data/koi-koi.tab.orig
diff --git a/src/data/koi-mac.tab b/src/data/koi-mac.tab
new file mode 100644
index 00000000000..c697c0cee12
--- /dev/null
+++ b/src/data/koi-mac.tab
@@ -0,0 +1,130 @@
+# Hmm ...
+#
+128 0xc0
+129 0xc1
+130 0xc2
+131 0xc3
+132 0xc4
+133 0xc5
+134 0xc6
+135 0xc7
+136 0xc8
+137 0xc9
+138 0xca
+139 0xcb
+140 0xcc
+141 0xcd
+142 0xce
+143 0xcf
+144 0xd0
+145 0xd1
+146 0xd2
+147 0xd3
+148 0xd4
+149 0xd5
+150 0xd6
+151 0xd7
+152 0xd8
+153 0xd9
+154 0xda
+155 0xdb
+156 0xdc
+157 0xdd
+158 0xde
+159 0xdf
+160 0xa0
+161 0xa1
+162 0xa2
+163 0xa3
+164 0xa4
+165 0xa5
+166 0xa6
+167 0xa7
+168 0xa8
+169 0xa9
+170 0xaa
+171 0xab
+172 0xac
+173 0xad
+174 0xae
+175 0xaf
+176 0xb0
+177 0xb1
+178 0xb2
+179 0xb3
+180 0xb4
+181 0xb5
+182 0xb6
+183 0xb7
+184 0xb8
+185 0xb9
+186 0xba
+187 0xbb
+188 0xbc
+189 0xbd
+190 0xbe
+191 0xbf
+192 0xfe
+193 0xe0
+194 0xe1
+195 0xf6
+196 0xe4
+197 0xe5
+198 0xf4
+199 0xe3
+200 0xf5
+201 0xe8
+202 0xe9
+203 0xea
+204 0xeb
+205 0xec
+206 0xed
+207 0xee
+208 0xef
+209 0xdf
+210 0xf0
+211 0xf1
+212 0xf2
+213 0xf3
+214 0xe6
+215 0xe2
+216 0xfc
+217 0xfb
+218 0xe7
+219 0xf8
+220 0xfd
+221 0xf9
+222 0xf7
+223 0xfa
+224 0x9e
+225 0x80
+226 0x81
+227 0x96
+228 0x84
+229 0x85
+230 0x94
+231 0x83
+232 0x95
+233 0x88
+234 0x89
+235 0x8a
+236 0x8b
+237 0x8c
+238 0x8d
+239 0x8e
+240 0x8f
+241 0x9f
+242 0x90
+243 0x91
+244 0x92
+245 0x93
+246 0x86
+247 0x82
+248 0x9c
+249 0x9b
+250 0x87
+251 0x98
+252 0x9d
+253 0x99
+254 0x97
+255 0x9a
diff --git a/src/data/koi-mac.tab.orig b/src/data/koi-mac.tab.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/data/koi-mac.tab.orig
diff --git a/src/data/koi-win.tab b/src/data/koi-win.tab
new file mode 100644
index 00000000000..4c390bc4eb3
--- /dev/null
+++ b/src/data/koi-win.tab
@@ -0,0 +1,85 @@
+# Line with '#' at the begin is comment
+# table file may contain number of line as you wana
+# first - code of symbol, second translate code of symbol
+# codes may be in two forms: decimal and hex
+# examples:
+# 192 225
+# 0x81 226
+# 226 0x81
+# 0x90 0xfe
+# patch for Russia by Dm.Kryukov (dvk@stack.serpukhov.su)
+#
+163 184
+164 186
+166 179
+167 191
+173 180
+179 168
+180 170
+182 178
+183 175
+189 165
+192 254
+193 224
+194 225
+195 246
+196 228
+197 229
+198 244
+199 227
+200 245
+201 232
+202 233
+203 234
+204 235
+205 236
+206 237
+207 238
+208 239
+209 255
+210 240
+211 241
+212 242
+213 243
+214 230
+215 226
+216 252
+217 251
+218 231
+219 248
+220 253
+221 249
+222 247
+223 250
+224 222
+225 192
+226 193
+227 214
+228 196
+229 197
+230 212
+231 195
+232 213
+233 200
+234 201
+235 202
+236 203
+237 204
+238 205
+239 206
+240 207
+241 223
+242 208
+243 209
+244 210
+245 211
+246 198
+247 194
+248 220
+249 219
+250 199
+251 216
+252 221
+253 217
+254 215
+255 218
diff --git a/src/data/koi-win.tab.orig b/src/data/koi-win.tab.orig
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/data/koi-win.tab.orig
diff --git a/src/include/config.h.in b/src/include/config.h.in
index f1f1dc1a8e6..c211c723483 100644
--- a/src/include/config.h.in
+++ b/src/include/config.h.in
@@ -195,6 +195,9 @@ extern void srandom(int seed);
/* Set to 1 if you want to USE_LOCALE */
#undef USE_LOCALE
+/* Set to 1 if you want CYR_RECODE (cyrillic recode) */
+#undef CYR_RECODE
+
/* Set to 1 if you want to Disable ASSERT CHECKING */
#undef NO_ASSERT_CHECKING
diff --git a/src/include/postgres.h b/src/include/postgres.h
index fde7c6c6bb8..f1d4704e46b 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1995, Regents of the University of California
*
- * $Id: postgres.h,v 1.11 1997/11/13 03:22:46 momjian Exp $
+ * $Id: postgres.h,v 1.12 1998/02/24 15:27:04 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -214,4 +214,12 @@ typedef uint32 CommandId;
#define STATUS_BAD_PACKET (-7)
#define STATUS_FOUND (1)
+/* ---------------
+ * Cyrillic on the fly charsets recode
+ * ---------------
+ */
+#ifdef CYR_RECODE
+void SetCharSet();
+#endif /* CYR_RECODE */
+
#endif /* POSTGRES_H */