📄 db_main.c
字号:
/****************************************************************************/
/* */
/* */
/* db_main.c v1.3 (c) 1987-1990 Ken Harris */
/* */
/* */
/****************************************************************************/
/* */
/* This software is made available on an AS-IS basis. Unrestricted */
/* use is granted provided that the copyright notice remains intact. */
/* The author makes no warranties expressed or implied. */
/* */
/****************************************************************************/
#include "dblib.h"
static char *copyright = "db V1.3 (c) 1987-1990 Ken Harris";
int db_error = 0;
ulong db_match_blk = 0;
ushort db_match_rec = 0;
ulong db_add_blk = 0;
ushort db_add_rec = 0;
/*
* db_create - Create a New Data File
*/
DATA_FILE db_create(path, fname, options)
char *path, *fname, *options;
{
BUFFER db_alloc_buf();
DATA_FILE df;
FILE_HDR fhdr;
char *fname_dflts(), *calloc();
db_error = 0;
df = (DATA_FILE) calloc(1, sizeof(struct db_data_file));
if (!df)
{ db_error = DB_ALLOC_ERROR;
return(NULL);
}
df->df_fhdr = db_alloc_buf(DB_FILE_HDR_SIZE);
fhdr = (FILE_HDR) df->df_fhdr->buf_data;
if (db_error) { db_free_df(df); return(NULL); }
df->df_fhdr->buf_cur_size = DB_FILE_HDR_SIZE;
strcpy(df->df_fname, fname_dflts(fname,path));
db_file_options(fhdr, options);
if (db_error) { db_free_df(df); return(NULL); }
db_fhdr_create(fhdr);
if (db_error) { db_free_df(df); return(NULL); }
#ifdef MSC
df->df_fd = open(df->df_fname, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
#endif
#ifdef TURBO
df->df_fd = open(df->df_fname, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
#endif
#ifdef ULTRIX
df->df_fd = open(df->df_fname, O_CREAT|O_TRUNC|O_RDWR, S_IREAD|S_IWRITE);
#endif
#ifdef SYSV
df->df_fd = open(df->df_fname, O_CREAT|O_TRUNC|O_RDWR, S_IREAD|S_IWRITE);
#endif
if (df->df_fd < 0)
{ db_error = DB_FILE_NOT_CREATED;
db_free_df(df);
return(NULL);
}
df->df_stat = DB_OPEN;
switch (fhdr->fh_file_type)
{
#ifdef IDX
case DB_INDEX:
df->df_buf = db_alloc_buf(fhdr->fh_block_size+2*fhdr->fh_rec_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
df->df_tmp = db_alloc_buf(fhdr->fh_block_size+2*fhdr->fh_rec_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
df->df_aux = db_alloc_buf(fhdr->fh_block_size+2*fhdr->fh_rec_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
df->df_buf->buf_size = fhdr->fh_block_size;
df->df_tmp->buf_size = fhdr->fh_block_size;
df->df_aux->buf_size = fhdr->fh_block_size;
break;
#endif
#ifdef RAN
case DB_RANDOM:
df->df_buf = db_alloc_buf(fhdr->fh_block_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
df->df_tmp = db_alloc_buf(fhdr->fh_block_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
while (fhdr->fh_last_block < fhdr->fh_base_size)
{ db_extend(df, df->df_buf);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
db_put_blk(df, df->df_buf);
}
break;
#endif
#ifdef SEQ
case DB_SEQ:
df->df_buf = db_alloc_buf(fhdr->fh_block_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
break;
#endif
#ifdef VAR
case DB_VAR:
df->df_buf = db_alloc_buf(fhdr->fh_block_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
break;
#endif
}
db_put_blk(df, df->df_fhdr);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
return(df);
}
/*
* db_file_options - parse and setup file options
*/
#define OPTION_SIZE 20
#define SUB_OPTION_SIZE 50
db_file_options(fh, option_str)
FILE_HDR fh;
char *option_str;
{
char option[OPTION_SIZE], sub_option[SUB_OPTION_SIZE];
char *c, *o_ptr, *s_ptr;
int cnt;
c = option_str;
while (*c)
{ while (*c && !isalpha(*c)) c++;
o_ptr = option;
s_ptr = sub_option;
*o_ptr = *s_ptr = NULL;
for (cnt=0; isalpha(*c); cnt++, c++)
{ if (cnt < OPTION_SIZE)
{ if (islower(*c))
*o_ptr++ = toupper(*c);
else
*o_ptr++ = *c;
}
}
while (*c && *c != '=' && *c != ',') c++;
if (*c == '=')
{ c++;
while (*c && *c <= ' ') c++;
for (cnt=0; *c && *c!=',' && !isspace(*c); cnt++, c++)
{ if (cnt < SUB_OPTION_SIZE)
*s_ptr++ = *c;
}
while (*c && *c != ',') c++;
}
*o_ptr++ = NULL;
*s_ptr++ = NULL;
db_file_1option(fh, option, sub_option);
if (db_error) return;
}
}
/*
* db_file_1option - Process one file option
*/
db_file_1option(fh, option, sub_option)
FILE_HDR fh;
char *option, *sub_option;
{
if (strcmp(option, "SEQ")==0)
{ if (fh->fh_file_type == 0)
fh->fh_file_type = DB_SEQ;
else
db_error = DB_FTYPE_ERROR;
}
else
if (strcmp(option, "RAN")==0)
{ if (fh->fh_file_type == 0)
fh->fh_file_type = DB_RANDOM;
else
db_error = DB_FTYPE_ERROR;
}
else
if (strcmp(option, "IDX")==0)
{ if (fh->fh_file_type == 0)
fh->fh_file_type = DB_INDEX;
else
db_error = DB_FTYPE_ERROR;
}
else
if (strcmp(option, "VAR")==0)
{ if (fh->fh_file_type == 0)
fh->fh_file_type = DB_VAR;
else
db_error = DB_FTYPE_ERROR;
}
else
if (strcmp(option, "BLK")==0)
fh->fh_block_size = atoi(sub_option);
else
if (strcmp(option, "REC")==0)
fh->fh_data_size = atoi(sub_option);
else
if (strcmp(option, "BASE")==0)
fh->fh_base_size = atoi(sub_option);
else
if (strcmp(option, "KEY")==0)
fh->fh_key_size = atoi(sub_option);
else
if (strcmp(option, "ATR")==0)
fh->fh_atr_size = atoi(sub_option);
else
if (strcmp(option, "MLINKS")==0)
fh->fh_mlink_cnt = atoi(sub_option);
else
if (strcmp(option, "OLINKS")==0)
fh->fh_olink_cnt = atoi(sub_option);
else
if (strcmp(option, "KLINKS")==0)
fh->fh_klink_cnt = atoi(sub_option);
else
if (strcmp(option, "DUPS")==0)
fh->fh_file_stat &= ~DB_DUP_ALLOWED;
else
if (strcmp(option, "NODUPS")==0)
fh->fh_file_stat |= DB_DUP_ALLOWED;
else
db_error = DB_INVALID_OPTION;
}
/*
* db_fhdr_create - Check file header data on create
*/
void db_fhdr_create(fh)
FILE_HDR fh;
{ short hdr_size;
db_error = 0;
fh->fh_db_version = DB_VERSION;
if (fh->fh_file_type != DB_SEQ &&
fh->fh_file_type != DB_RANDOM &&
fh->fh_file_type != DB_INDEX &&
fh->fh_file_type != DB_VAR)
{ db_error = DB_INVALID_FHDR;
return;
}
#ifndef SEQ
if (fh->fh_file_type == DB_SEQ)
{ db_error = DB_UNSUPP_FEATURE;
return;
}
#endif
#ifndef RAN
if (fh->fh_file_type == DB_RANDOM)
{ db_error = DB_UNSUPP_FEATURE;
return;
}
#endif
#ifndef IDX
if (fh->fh_file_type == DB_INDEX)
{ db_error = DB_UNSUPP_FEATURE;
return;
}
#endif
#ifndef VAR
if (fh->fh_file_type == DB_VAR)
{ db_error = DB_UNSUPP_FEATURE;
return;
}
#endif
fh->fh_file_stat &= ~DB_OPEN;
fh->fh_last_block = 0;
if (!fh->fh_block_size) fh->fh_block_size = 512;
switch (fh->fh_file_type)
{
#ifdef SEQ
case DB_SEQ:
hdr_size = 0;
if (!fh->fh_ctl_size) fh->fh_ctl_size = 1;
if (fh->fh_ctl_size & 1) fh->fh_ctl_size++;
break;
#endif
#ifdef RAN
case DB_RANDOM:
hdr_size = sizeof(struct db_random_uhdr);
if (!fh->fh_base_size)
{ db_error = DB_INVALID_FHDR;
return;
}
if (!fh->fh_ctl_size) fh->fh_ctl_size = 1;
break;
#endif
#ifdef IDX
case DB_INDEX:
if (!fh->fh_ctl_size) fh->fh_ctl_size = 2;
hdr_size = sizeof(struct db_index_hdr) + fh->fh_ctl_size;
break;
#endif
#ifdef VAR
case DB_VAR:
hdr_size = 0;
if (!fh->fh_ctl_size) fh->fh_ctl_size = sizeof(struct db_var_rec);
if (!fh->fh_data_size) fh->fh_data_size = 512;
fh->fh_block_size = fh->fh_ctl_size + fh->fh_data_size;
fh->fh_vfile_size = DB_FILE_HDR_SIZE;
break;
#endif
default:
hdr_size = 0;
break;
}
fh->fh_ctl_size = fh->fh_ctl_size
+ fh->fh_olink_cnt * sizeof(struct db_owner_link)
+ fh->fh_mlink_cnt * sizeof(struct db_member_link)
+ fh->fh_klink_cnt * sizeof(struct db_key_link);
fh->fh_rec_size = fh->fh_ctl_size + fh->fh_data_size;
if (fh->fh_file_type == DB_VAR)
fh->fh_block_size = fh->fh_rec_size;
else
if (fh->fh_file_type == DB_INDEX)
{ if (fh->fh_block_size < 2 * fh->fh_rec_size + hdr_size)
fh->fh_block_size = 2 * fh->fh_rec_size + hdr_size;
fh->fh_block_size = ((fh->fh_block_size + 511) / 512) * 512;
}
else
{ if (fh->fh_block_size < fh->fh_rec_size + hdr_size)
fh->fh_block_size = fh->fh_rec_size + hdr_size;
fh->fh_block_size = ((fh->fh_block_size + 511) / 512) * 512;
}
fh->fh_rec_cnt = 0;
fh->fh_recs_per_blk = (fh->fh_block_size - hdr_size) / fh->fh_rec_size;
fh->fh_root_ptr = 0;
fh->fh_next_avail = 0;
if (fh->fh_key_size > fh->fh_data_size)
{ db_error = DB_INVALID_FHDR;
return;
}
}
/*
* db_open - Open a Data File
*/
DATA_FILE db_open(path,fname)
char *path, *fname;
{
BUFFER db_alloc_buf();
DATA_FILE df;
FILE_HDR fhdr;
char *fname_dflts(), *calloc();
int cnt;
db_error = 0;
df = (DATA_FILE) calloc(1, sizeof(struct db_data_file));
if (!df)
{ db_error = DB_ALLOC_ERROR;
return(NULL);
}
df->df_fhdr = db_alloc_buf(DB_FILE_HDR_SIZE);
fhdr = (FILE_HDR) df->df_fhdr->buf_data;
if (db_error) { db_free_df(df); return(NULL); }
strcpy(df->df_fname, fname_dflts(fname,path));
#ifdef MSC
df->df_fd = open(df->df_fname, O_RDWR|O_BINARY);
#endif
#ifdef TURBO
df->df_fd = open(df->df_fname, O_RDWR|O_BINARY);
#endif
#ifdef ULTRIX
df->df_fd = open(df->df_fname, O_RDWR);
#endif
#ifdef SYSV
df->df_fd = open(df->df_fname, O_RDWR);
#endif
if (df->df_fd < 0)
{ db_error = DB_FILE_NOT_FOUND;
db_free_df(df);
return(NULL);
}
df->df_stat = DB_OPEN;
db_get_blk(df, 0L, df->df_fhdr);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
switch (fhdr->fh_file_type)
{
#ifdef IDX
case DB_INDEX:
df->df_buf = db_alloc_buf(fhdr->fh_block_size+2*fhdr->fh_rec_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
df->df_tmp = db_alloc_buf(fhdr->fh_block_size+2*fhdr->fh_rec_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
df->df_aux = db_alloc_buf(fhdr->fh_block_size+2*fhdr->fh_rec_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
df->df_buf->buf_size = fhdr->fh_block_size;
df->df_tmp->buf_size = fhdr->fh_block_size;
df->df_aux->buf_size = fhdr->fh_block_size;
break;
#endif
#ifdef RAN
case DB_RANDOM:
df->df_buf = db_alloc_buf(fhdr->fh_block_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
df->df_tmp = db_alloc_buf(fhdr->fh_block_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
break;
#endif
#ifdef SEQ
case DB_SEQ:
df->df_buf = db_alloc_buf(fhdr->fh_block_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
break;
#endif
#ifdef VAR
case DB_VAR:
df->df_buf = db_alloc_buf(fhdr->fh_block_size);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
break;
#endif
}
db_fhdr_open(fhdr);
if (db_error) { close(df->df_fd); db_free_df(df); return(NULL); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -