aboutsummaryrefslogtreecommitdiff
path: root/src/dbbegdbm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dbbegdbm.c')
-rw-r--r--src/dbbegdbm.c221
1 files changed, 38 insertions, 183 deletions
diff --git a/src/dbbegdbm.c b/src/dbbegdbm.c
index 1e2702028..6c2659a80 100644
--- a/src/dbbegdbm.c
+++ b/src/dbbegdbm.c
@@ -30,7 +30,7 @@
** relatively simple to convert to a different database such
** as NDBM, SDBM, or BerkeleyDB.
**
-** $Id: dbbegdbm.c,v 1.1 2000/10/19 01:49:02 drh Exp $
+** $Id: dbbegdbm.c,v 1.2 2001/01/13 14:34:06 drh Exp $
*/
#include "sqliteInt.h"
#include <gdbm.h>
@@ -58,33 +58,14 @@ struct BeFile {
};
/*
-** The following structure holds the current state of the RC4 algorithm.
-** We use RC4 as a random number generator. Each call to RC4 gives
-** a random 8-bit number.
-**
-** Nothing in this file or anywhere else in SQLite does any kind of
-** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
-** number generator) not as an encryption device.
-*/
-struct rc4 {
- int i, j;
- int s[256];
-};
-
-/*
** The following structure contains all information used by GDBM
** database driver. This is a subclass of the Dbbe structure.
*/
typedef struct Dbbex Dbbex;
struct Dbbex {
Dbbe dbbe; /* The base class */
- char *zDir; /* The directory containing the database */
int write; /* True for write permission */
BeFile *pOpen; /* List of open files */
- int nTemp; /* Number of temporary files created */
- FILE **apTemp; /* Space to hold temporary file pointers */
- char **azTemp; /* Names of the temporary files */
- struct rc4 rc4; /* The random number generator */
};
/*
@@ -105,41 +86,12 @@ struct DbbeCursor {
};
/*
-** Initialize the RC4 PRNG. "seed" is a pointer to some random
-** data used to initialize the PRNG.
-*/
-static void rc4init(struct rc4 *p, char *seed, int seedlen){
- int i;
- char k[256];
- p->j = 0;
- p->i = 0;
- for(i=0; i<256; i++){
- p->s[i] = i;
- k[i] = seed[i%seedlen];
- }
- for(i=0; i<256; i++){
- int t;
- p->j = (p->j + p->s[i] + k[i]) & 0xff;
- t = p->s[p->j];
- p->s[p->j] = p->s[i];
- p->s[i] = t;
- }
-}
-
-/*
-** Get a single 8-bit random value from the RC4 PRNG.
+**
*/
-static int rc4byte(struct rc4 *p){
- int t;
- p->i = (p->i + 1) & 0xff;
- p->j = (p->j + p->s[p->i]) & 0xff;
- t = p->s[p->i];
- p->s[p->i] = p->s[p->j];
- p->s[p->j] = t;
- t = p->s[p->i] + p->s[p->j];
- return t & 0xff;
-}
-
+struct DbbeList {
+ FILE *pOut;
+ Dbbe *pDbbe;
+};
/*
** The "mkdir()" function only takes one argument under Windows.
*/
@@ -165,18 +117,7 @@ static void sqliteGdbmClose(Dbbe *pDbbe){
memset(pFile, 0, sizeof(*pFile));
sqliteFree(pFile);
}
- for(i=0; i<pBe->nTemp; i++){
- if( pBe->apTemp[i]!=0 ){
- unlink(pBe->azTemp[i]);
- fclose(pBe->apTemp[i]);
- sqliteFree(pBe->azTemp[i]);
- pBe->apTemp[i] = 0;
- pBe->azTemp[i] = 0;
- break;
- }
- }
- sqliteFree(pBe->azTemp);
- sqliteFree(pBe->apTemp);
+ sqliteDbbeCloseAllTempFiles(pDbbe);
memset(pBe, 0, sizeof(*pBe));
sqliteFree(pBe);
}
@@ -190,9 +131,9 @@ static void sqliteGdbmClose(Dbbe *pDbbe){
static char *sqliteFileOfTable(Dbbex *pBe, const char *zTable){
char *zFile = 0;
int i;
- sqliteSetString(&zFile, pBe->zDir, "/", zTable, ".tbl", 0);
+ sqliteSetString(&zFile, pBe->dbbe.zDir, "/", zTable, ".tbl", 0);
if( zFile==0 ) return 0;
- for(i=strlen(pBe->zDir)+1; zFile[i]; i++){
+ for(i=strlen(pBe->dbbe.zDir)+1; zFile[i]; i++){
int c = zFile[i];
if( isupper(c) ){
zFile[i] = tolower(c);
@@ -204,27 +145,6 @@ static char *sqliteFileOfTable(Dbbex *pBe, const char *zTable){
}
/*
-** Generate a random filename with the given prefix. The new filename
-** is written into zBuf[]. The calling function must insure that
-** zBuf[] is big enough to hold the prefix plus 20 or so extra
-** characters.
-**
-** Very random names are chosen so that the chance of a
-** collision with an existing filename is very very small.
-*/
-static void randomName(struct rc4 *pRc4, char *zBuf, char *zPrefix){
- int i, j;
- static const char zRandomChars[] = "abcdefghijklmnopqrstuvwxyz0123456789";
- strcpy(zBuf, zPrefix);
- j = strlen(zBuf);
- for(i=0; i<15; i++){
- int c = rc4byte(pRc4) % (sizeof(zRandomChars) - 1);
- zBuf[j++] = zRandomChars[c];
- }
- zBuf[j] = 0;
-}
-
-/*
** Open a new table cursor. Write a pointer to the corresponding
** DbbeCursor structure into *ppCursr. Return an integer success
** code:
@@ -295,13 +215,11 @@ static int sqliteGdbmOpenCursor(
}
}else{
int limit;
- struct rc4 *pRc4;
char zRandom[50];
- pRc4 = &pBe->rc4;
zFile = 0;
limit = 5;
do {
- randomName(&pBe->rc4, zRandom, "_temp_table_");
+ sqliteRandomName(zRandom, "_temp_table_");
sqliteFree(zFile);
zFile = sqliteFileOfTable(pBe, zRandom);
pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0);
@@ -577,15 +495,10 @@ static int sqliteGdbmNew(DbbeCursor *pCursr){
datum key;
int go = 1;
int i;
- struct rc4 *pRc4;
if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return 1;
- pRc4 = &pCursr->pBe->rc4;
while( go ){
- iKey = 0;
- for(i=0; i<4; i++){
- iKey = (iKey<<8) + rc4byte(pRc4);
- }
+ iKey = sqliteRandomInteger();
if( iKey==0 ) continue;
key.dptr = (char*)&iKey;
key.dsize = 4;
@@ -631,68 +544,31 @@ static int sqliteGdbmDelete(DbbeCursor *pCursr, int nKey, char *pKey){
}
/*
-** Open a temporary file. The file should be deleted when closed.
-**
-** Note that we can't use the old Unix trick of opening the file
-** and then immediately unlinking the file. That works great
-** under Unix, but fails when we try to port to Windows.
+** This variable contains pointers to all of the access methods
+** used to implement the GDBM backend.
*/
-static int sqliteGdbmOpenTempFile(Dbbe *pDbbe, FILE **ppFile){
- char *zFile; /* Full name of the temporary file */
- char zBuf[50]; /* Base name of the temporary file */
- int i; /* Loop counter */
- int limit; /* Prevent an infinite loop */
- int rc = SQLITE_OK; /* Value returned by this function */
- Dbbex *pBe = (Dbbex*)pDbbe;
-
- for(i=0; i<pBe->nTemp; i++){
- if( pBe->apTemp[i]==0 ) break;
- }
- if( i>=pBe->nTemp ){
- pBe->nTemp++;
- pBe->apTemp = sqliteRealloc(pBe->apTemp, pBe->nTemp*sizeof(FILE*) );
- pBe->azTemp = sqliteRealloc(pBe->azTemp, pBe->nTemp*sizeof(char*) );
- }
- if( pBe->apTemp==0 ){
- *ppFile = 0;
- return SQLITE_NOMEM;
- }
- limit = 4;
- zFile = 0;
- do{
- randomName(&pBe->rc4, zBuf, "/_temp_file_");
- sqliteFree(zFile);
- zFile = 0;
- sqliteSetString(&zFile, pBe->zDir, zBuf, 0);
- }while( access(zFile,0)==0 && limit-- >= 0 );
- *ppFile = pBe->apTemp[i] = fopen(zFile, "w+");
- if( pBe->apTemp[i]==0 ){
- rc = SQLITE_ERROR;
- sqliteFree(zFile);
- pBe->azTemp[i] = 0;
- }else{
- pBe->azTemp[i] = zFile;
- }
- return rc;
-}
-
-/*
-** Close a temporary file opened using sqliteGdbmOpenTempFile()
-*/
-static void sqliteGdbmCloseTempFile(Dbbe *pDbbe, FILE *f){
- int i;
- Dbbex *pBe = (Dbbex*)pDbbe;
- for(i=0; i<pBe->nTemp; i++){
- if( pBe->apTemp[i]==f ){
- unlink(pBe->azTemp[i]);
- sqliteFree(pBe->azTemp[i]);
- pBe->apTemp[i] = 0;
- pBe->azTemp[i] = 0;
- break;
- }
- }
- fclose(f);
-}
+static struct DbbeMethods gdbmMethods = {
+ /* n Close */ sqliteGdbmClose,
+ /* OpenCursor */ sqliteGdbmOpenCursor,
+ /* DropTable */ sqliteGdbmDropTable,
+ /* ReorganizeTable */ sqliteGdbmReorganizeTable,
+ /* CloseCursor */ sqliteGdbmCloseCursor,
+ /* Fetch */ sqliteGdbmFetch,
+ /* Test */ sqliteGdbmTest,
+ /* CopyKey */ sqliteGdbmCopyKey,
+ /* CopyData */ sqliteGdbmCopyData,
+ /* ReadKey */ sqliteGdbmReadKey,
+ /* ReadData */ sqliteGdbmReadData,
+ /* KeyLength */ sqliteGdbmKeyLength,
+ /* DataLength */ sqliteGdbmDataLength,
+ /* NextKey */ sqliteGdbmNextKey,
+ /* Rewind */ sqliteGdbmRewind,
+ /* New */ sqliteGdbmNew,
+ /* Put */ sqliteGdbmPut,
+ /* Delete */ sqliteGdbmDelete,
+ /* OpenTempFile */ sqliteDbbeOpenTempFile,
+ /* CloseTempFile */ sqliteDbbeCloseTempFile
+};
/*
@@ -746,31 +622,10 @@ Dbbe *sqliteGdbmOpen(
sqliteSetString(pzErrMsg, "out of memory", 0);
return 0;
}
- pNew->dbbe.Close = sqliteGdbmClose;
- pNew->dbbe.OpenCursor = sqliteGdbmOpenCursor;
- pNew->dbbe.DropTable = sqliteGdbmDropTable;
- pNew->dbbe.ReorganizeTable = sqliteGdbmReorganizeTable;
- pNew->dbbe.CloseCursor = sqliteGdbmCloseCursor;
- pNew->dbbe.Fetch = sqliteGdbmFetch;
- pNew->dbbe.Test = sqliteGdbmTest;
- pNew->dbbe.CopyKey = sqliteGdbmCopyKey;
- pNew->dbbe.CopyData = sqliteGdbmCopyData;
- pNew->dbbe.ReadKey = sqliteGdbmReadKey;
- pNew->dbbe.ReadData = sqliteGdbmReadData;
- pNew->dbbe.KeyLength = sqliteGdbmKeyLength;
- pNew->dbbe.DataLength = sqliteGdbmDataLength;
- pNew->dbbe.NextKey = sqliteGdbmNextKey;
- pNew->dbbe.Rewind = sqliteGdbmRewind;
- pNew->dbbe.New = sqliteGdbmNew;
- pNew->dbbe.Put = sqliteGdbmPut;
- pNew->dbbe.Delete = sqliteGdbmDelete;
- pNew->dbbe.OpenTempFile = sqliteGdbmOpenTempFile;
- pNew->dbbe.CloseTempFile = sqliteGdbmCloseTempFile;
- pNew->zDir = (char*)&pNew[1];
- strcpy(pNew->zDir, zName);
+ pNew->dbbe.x = &gdbmMethods;
+ pNew->dbbe.zDir = (char*)&pNew[1];
+ strcpy(pNew->dbbe.zDir, zName);
pNew->write = writeFlag;
pNew->pOpen = 0;
- time(&statbuf.st_ctime);
- rc4init(&pNew->rc4, (char*)&statbuf, sizeof(statbuf));
return &pNew->dbbe;
}