diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/libpq/hba.c | 188 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 22 | ||||
-rw-r--r-- | src/backend/tcop/postgres.c | 8 | ||||
-rw-r--r-- | src/backend/utils/adt/varchar.c | 25 | ||||
-rw-r--r-- | src/backend/utils/adt/varlena.c | 12 | ||||
-rw-r--r-- | src/backend/utils/init/miscinit.c | 146 |
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 * |