Category : Files from Magazines
Archive   : CUJ9301.ZIP
Filename : 1101083A

 
Output of file : 1101083A contained in archive : CUJ9301.ZIP
//////////////
// Isam.cpp //
//////////////

#include "isam.h"
#include
#include
#include
#include
#include
#include

static struct BTParms {
char name[9], filename[9];
int keylen, dreclen, maxrecs, indxfd, datafd,
kstart, count;
t_func keygen;
} btparms[40];

static int items = 0;

extern "C" {
int (*Write)(int,const void *,unsigned) = write;
int (*Read )(int,void *,unsigned) = read;
}
static void isam_init(void);

static void isam_init(void)
{
ifstream btr("btparms.btr");
char nwln, item[81], buf[20], fname[13], fcname[9];
int i;

if (!btr)
eprintf("\n\nUnable to open btparms.btr.\n");

for (i = 0; i < 40; i++) {
btr.get (item, 80);
if (!strlen(item))
break;
btr.get(nwln);
strcpy(btparms[i].name, strtok(item, "^"));
strtok(NULL, "^");
strcpy(buf, strtok(NULL, "^"));
btparms[i].keylen = atoi(buf);
strtok(NULL, "^");
strcpy(buf, strtok(NULL, "^"));
btparms[i].dreclen = atoi(buf);
strtok(NULL, "^");
strcpy(fname, strtok(NULL, "^"));
strtok(NULL, "^");
strcpy(buf, strtok(NULL, "^"));
btparms[i].kstart = atoi(buf);
strcpy(fcname, nospace(strtok(NULL, "^")));
strcpy(btparms[i].filename, strtok(fname,"."));
btparms[i].count = 0;
btparms[i].indxfd = btparms[i].datafd = -1;
if (strlen(fcname))
btparms[i].keygen = cataloged_func (
catalog_number(fcname));
else
btparms[i].keygen = (t_func) NULL;
}

items = i;
btr.close();

if (!items)
eprintf("\n\nUnable to initialize isam system.\n");

for (i = items; i < 40; i++) {
strcpy(btparms[i].name,"");
strcpy(btparms[i].filename,"");
btparms[i].keygen = NULL;
btparms[i].keylen = btparms[i].dreclen =
btparms[i].count = btparms[i].kstart = 0;
btparms[i].indxfd = btparms[i].datafd = -1;
}
}

Isam::Isam(const char *datafilename, int e)
{
int i, j;
char buf[20];

backingout = 0;
elements = e;
if (!items) // this is the first Isam

isam_init(); // initialize btparms

strcpy(buf, nospace(datafilename));
indices = 0;
// find btree params
for (i = 0; i < items; i++)
if (!stricmp(buf, btparms[i].filename))
btr[indices++] = i;
if (!indices) // couldn't find any, fatal
eprintf("\n\nCan't find parameters for %s!\n",
datafilename);
// set up btree interfaces
if( !(btc = new BTC [indices]) ||
!(inames = new char* [indices]) ||
!(loc = new long [elements]) ||
!(oldrec = new char* [elements]) ||
!(rec = new char* [elements]) ||
!(okey = new char [btparms[*btr].dreclen])||
!(nkey = new char [btparms[*btr].dreclen]) )
eprintf("\n\nOut of memory.\n");
for (i = 0; i < indices; i++) {
inames[i] = btparms[btr[i]].name;
btc[i].btvcount = 1;
if (btrinit(inames[i], btc+i) == ERR)
eprintf("\n\nCouldn't initialize %s.\n",
inames[i]);
btc[i].btmulti = 0; // record locking off
}
for (i = 0; i < elements; i++) {
loc[i] = 0L;
if (!(oldrec[i] = new char
[btparms[*btr].dreclen + 1]) ||
!(rec[i] = new char
[btparms[*btr].dreclen + 1]) )
eprintf("\n\nOut of memory.\n");
}
if (btparms[*btr].count) { // open files if neccesary
fd[0] = btparms[*btr].datafd;
fd[1] = btparms[*btr].indxfd;
}
else { // yup, it's neccesary
strcpy(buf, btparms[*btr].filename);
strcat(buf, ".dat");
if ((fd[0]=bt_open(buf, O_RDWR,S_IRDWR)) == ERR)
eprintf("\n\nCan't open %s.\n", buf);
strcpy(buf, btparms[*btr].filename);
strcat(buf, ".idx");
if ((fd[1]=bt_open(buf, O_RDWR,S_IRDWR)) == ERR)
eprintf("\n\nCan't open %s.\n", buf);
btparms[*btr].datafd = fd[0];
btparms[*btr].indxfd = fd[1];
}

(btparms[*btr].count)++; // record that we are here
clear();
}

Isam::~Isam()
{
int i, j;
// clean up out mess
for (i = 0; i < indices; i++)
btrterm(btc+i);
for (i = 0; i < elements; i++) {
delete [] oldrec[i];
delete [] rec[i];
}
delete [] btc;
delete [] inames;
delete [] loc;
delete [] oldrec;
delete [] rec;
delete [] nkey;
delete [] okey;
// if we're last ones out, turn off the lights
if (!(--(btparms[*btr].count))) {
close (fd[0]);
close (fd[1]);
btparms[*btr].indxfd = -1;
btparms[*btr].datafd = -1;
}
}

int Isam::write ()
{
int deltakey, old1, new1, ele, index, result, len,
start, notfirst;
t_func fcn;
if (*loc < 0) // programmer hasn't followed rules
eprintf ("No writes after gets!");
for (ele = 0; ele < elements; ele++) {
old1 = strlen(oldrec[ele]);
new1 = strlen( rec[ele]);
if (!(old1 || new1) ||
!strcmp(oldrec[ele], rec[ele]))
continue;
for (index = 0; index < indices; index++) {
// generate the old and/or new key
len = btparms[btr[index]].keylen;
start = btparms[btr[index]].kstart;
if ((fcn = btparms[btr[index]].keygen) !=
(t_func) NULL) {
if (old1)
strcpy(okey, fcn(oldrec[ele]));
if (new1)
strcpy(nkey, fcn( rec[ele]));
}
else {
if (old1)
strnncpy(okey, oldrec[ele] + start, len);
if (new1)
strnncpy(nkey, rec[ele] + start, len);
}
deltakey = (!old1||!new1||stricmp(okey,nkey));

if (old1 && deltakey) {
notfirst = 0;
while (strlen(okey) >= len) {
strnncpy(btc[index].btkey, ToUpper(okey),
len);
btc[index].btoptype = (new1 || index ||
notfirst++ || backingout) ? DELTKY
: DELETE;
btc[index].btloc = loc[ele];
result=cbtree(fd[0], fd[1], btc+index);
if (result != BTCALLOK)
backout (ele, 'D', index, result);
strcpy(okey, okey + len);
}
}
if (new1 && deltakey) {
notfirst = 0;
while (strlen(nkey) >= len) {
strnncpy(btc[index].btkey, ToUpper(nkey),
len);
btc[index].btoptype = (loc[ele] == 0L) ?
INSERT : ISRTKY;
btc[index].btloc = loc[ele];
result = cbtree(fd[0], fd[1], btc+index);
if (result == BTCALLOK)
loc[ele] = btc[index].btloc;
else
backout(ele, 'I', index, result);
strcpy(nkey, nkey + len);
}
}
}
if (!new1)
continue;
if (btseek (fd[0], loc[ele], btc->btdtalen)
== -1L)
backout(ele, 'S');
if (Write(fd[0],rec[ele],(unsigned)btc->btdtalen)
!= btc->btdtalen)
backout(ele, 'W');
}
clear ();
return 0;
}

void Isam::backout(int ele,char op,int index,int result)
{ // backs out record add/change/delete on error
char *trec;
if (!(trec = new char [btparms[*btr].dreclen]) ||
backingout) // I quit! Error in error backout!
eprintf("\n\nBackout error, error type was %c\n",
backingout);
if (index >= 0)
indices = index + 1; // those beyond index are ok
backingout = op;
elements = 1;
strcpy(trec,rec[ele]);
strcpy(rec[0],oldrec[ele]);
strcpy(oldrec[0],trec);
loc[0] = loc[ele];
write();
switch (backingout) {
case 'I':
eprintf(
"\n\nINSERT error, element %d, index %s, result %d\n",
ele, inames[index], result);
case 'D':
eprintf(
"\n\nDELETE error, element %d, index %s, result %d\n",
ele, inames[index], result);
case 'S':
eprintf ("\n\nSeek error, element %d\n", ele);
case 'W':
eprintf ("\n\nWrite error, element %d\n", ele);
}
}

int Isam::read(const char *key, int ele_limit, int idx,
int ele)
{
int i = 0, j = 0;

if ((ele_limit + ele) > elements)
eprintf("\n\nNot enough elements!\n");
free_svkey(btc+idx);
btc[idx].btoptype = GETALL;
strcpy(btc[idx].btkey, ToUpper(key));
btc[idx].btloc = 0L;
while (cbtree(fd[0], fd[1], btc + idx) == BTCALLOK) {
while (btc[idx].btrecnum[i-j] != 0L) {
if (i < ele_limit) {
loc[i+ele] = btc[idx].btrecnum[i-j];
btseek(fd[0], loc[i+ele], btc[idx].btdtalen);
Read (fd[0], rec[i+ele], btc[idx].btdtalen);
}
i++;
if (!((i-j) < btc[idx].btmax))
break;
}
if ((i-j) < btc[idx].btmax)
break;
j += btc[idx].btmax;
}
for (j = 0; j < ele_limit; j++)
strcpy(oldrec[j], rec[j]);
return i;
}

int Isam::getfirst(int index)
{
return getxxx (index, GETFRST);
}

int Isam::getnext(int index)
{
return getxxx (index, GETNXT);
}

int Isam::getge (char *key, int index)
{
*loc = -1;
btc[index].btoptype = GETGE;
strcpy(btc[index].btkey, ToUpper(key));
if (!(cbtree(fd[0], fd[1], btc + index) == BTCALLOK))
return 0;
btseek(fd[0], btc[index].btloc, btc[index].btdtalen);
Read (fd[0], rec[0], btc[index].btdtalen);
return 1;
}

int Isam::getxxx(int index, int opt)
{
*loc = -1;
btc[index].btoptype = opt;
if (!(cbtree(fd[0], fd[1], btc + index) == BTCALLOK))
return 0;
btseek(fd[0], btc[index].btloc, btc[index].btdtalen);
Read (fd[0], rec[0], btc[index].btdtalen);
return 1;
}

void Isam::clear()
{
int i;
for (i = 0; i < elements; i++) {
loc[i] = 0L;
memset (oldrec[i],'\0', btparms[*btr].dreclen + 1);
memset ( rec[i],'\0', btparms[*btr].dreclen + 1);
}
}

int Isam::keynum (const char *btname)
{
int i;

if (!items)
eprintf("\n\nBtparms not initialized!\n");
if (indices < 1)
eprintf("\n\nNo indices.\n");
for (i = 0; i < indices; i++)
if (!stricmp(inames[i], nospace(btname)))
return i;
eprintf ("\n\nIndex %s not found.\n", btname);
return -1;
}

char* nospace(const char *arg)
{
static char rtn[80];
int i, j = 0, k = strlen(arg);
for (i = 0; i < k; i++)
if (arg[i] != ' ')
rtn[j++] = arg[i];
rtn[j] = '\0';
return rtn;
}

int eprintf(const char *format, ... )
{
int rtn;
va_list argptr;
va_start(argptr, format);
rtn = vprintf(format, argptr);
va_end (argptr);
exit (1);
return rtn;
}

char *ToUpper(const char *c)
{
static char d[257];
int i;

for (i = 0; i < 256, c[i] != '\0'; i++)
d[i] = toupper(c[i]);
d[i] = '\0';
return d;
}

void Isam::reindex(rel_func func)
{
char buf[20], cmd[80];
int tad, i, rlen = btparms[*btr].dreclen, x, y;
long l;

clear();
strcpy(buf, btparms[*btr].filename);
strcat(buf, ".tad");
if (bt_open(buf, O_RDWR,S_IRDWR) != ERR)
// I can't cook in a dirty kitchen!
// Besides that, the last re-index
// must have failed and I don't know
// where the real data is, now.
eprintf("\n\n%s still exists!\n", buf);
sprintf(cmd, "ren %s.dat %s.tad",
btparms[*btr].filename, btparms[*btr].filename);
close (fd[0]);
system (cmd); // ren .dat to .tad
if ((tad = bt_open(buf, O_RDWR,S_IRDWR)) == ERR)
eprintf("\n\nCan't open %s\n", buf);// ren didn't go
strcpy(buf, btparms[*btr].filename); // recreate .dat
strcat(buf, ".dat");
if((fd[0]=bt_open(buf, O_NEW|O_RDWR, S_IRDWR) ) == ERR)
eprintf ("\n\nCouldn't recreate %s.dat\n",
btparms[*btr].filename);
initdat(fd[0], btc); // create file header
btparms[*btr].datafd = fd[0];
strcpy(buf, btparms[*btr].filename); // unlink .idx
strcat(buf, ".idx");
close (fd[1]);
unlink (buf);
for (i = 0; i < indices; i++) {
btrterm(btc + i); // to btrinit() with no .idx
if (btrinit(inames[i], btc+i) == ERR)
eprintf("\n\nCouldn't re-initialize %s.\n",
inames[i]);
creatbtr(btc + i);
}
for (i = 0; i < indices; i++) { // re-initialize
btrterm(btc + i);
if (btrinit(inames[i], btc+i) == ERR)
eprintf("\n\nCouldn't re-initialize %s.\n",
inames[i]);
} // We now have empty datafile and indexfile
strcpy(buf, btparms[*btr].filename); // re-open .idx
strcat(buf, ".idx");
if((fd[1]=bt_open(buf, O_RDWR, S_IRDWR) ) == ERR)
eprintf ("\n\nCouldn't recreate %s.idx\n",
btparms[*btr].filename);
btparms[*btr].indxfd = fd[1];
clrscr(); // we're ready
l = 2L; i = 0;
while (1) {
if (!(l%10)) {
if (l < 11L) {
gotoxy(10,10);
cprintf("Processing %s location ",
btparms[*btr].filename);
x = wherex(); y = wherey();
}
gotoxy(x, y);
cprintf("%ld", l);
}
btseek(tad, l++, rlen);
if (Read (tad, *rec, rlen) == rlen) {
if (**rec != '~') {
if (func)
if (func(*rec))
continue;
write();
i++;
}
}
else
break;
}
printf ("\n\n%d records added.\n", i);
close (tad);
strcpy(buf, btparms[*btr].filename);
strcat(buf, ".tad");
unlink (buf); // clean kitchen for next time
}



  3 Responses to “Category : Files from Magazines
Archive   : CUJ9301.ZIP
Filename : 1101083A

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/