aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-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
6 files changed, 394 insertions, 7 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
*