home *** CD-ROM | disk | FTP | other *** search
- /* ******************************************************************** *
- *** unix compatible ***
- * MetalBase 3.0..................................................... *
- * *
- * Multi-user simultaneous use of relations (On multi-user hardware) *
- * Users may have many relations open at once, even the same one! *
- * Unlimited length records (Really! Just redefine BUF_LEN!) *
- * Up to 20 indicies per relation, 5 fields max per composite index *
- * Up to 4.2 billion records per relation *
- * Bizzare intermittent bugs, just like the expensive programs *
- * And, unless they're weird, your kids will eat it *
- * /\ *
- * Written starting August 1989, by Huan-Ti rj / \ *
- * / \ *
- * "Ye hath mushrooms for $1.99 a pound. Ye art \ / *
- * truly a Calvinist." \ / tp *
- * -- II Calvin 7:1 \/ *
- * *
- * 713/630-8962 <-----= May 26, 1996 =-----> 615/494-0220 *
- *** ***
- * ******************************************************************** */
-
- #include "stdinc.h"
-
- #define BUF_LEN 256 /* Record_length + 13*number_of_indicies */
- #define MAX_REL 5 /* For this user. DOES NOT CHANGE STDIO'S # ! */
- #define MAX_FLDS 30 /* Fields/rel. If you need more than 30, redefine */
-
- #define OKAY 0 /* Generic no-problem number. Thank IBM. */
- #define NOT_ENOUGH_ROOM -1000 /* Too many files are open at once */
- #define CANNOT_OPEN_REL -1001 /* Can't open FILE.REL */
- #define RELATION_HUNG -1002 /* User left during add/del/upd. See dox */
- #define CANNOT_READ_REL -1003 /* FILE.REL is protected (Need rw access) */
- #define RELATION_BUSY -1004 /* 120 users on one relation=max (Hah!) */
- #define RELATION_LOCKED -1005 /* Someone has locked the relation */
- #define LOCK_DENIED -1006 /* Can't lock with other users. See dox */
- #define ILLEGAL_DUPLICATE -1007 /* Record would violate a nodups index */
- #define CORRUPT_INDEX -1008 /* Means you're fucked. Probly not used */
- #define INVALID_FILE_CODE -1009 /* You've passed an unreal relation numb */
- #define NOT_OPEN -1010 /* You've tried to work with a closed rel */
- #define RCD_INVALID -1011 /* Bad-size or # of flds given to add/upd */
- #define INVALID_COMP -1012 /* SELECT's record for comparison is bad */
- #define UNKNOWN_ACTION -1013 /* You'll probly never get this one. */
- #define NOT_FOUND -1014 /* Generic. Can't find the record U want */
- #define NO_CURRENT_RECORD -1015 /* Must select a record before del/upd */
- #define INVALID_INDEX -1016 /* A bad index # has been sent to mb_sel */
-
- #define CURR 1 /* Re-read the current record (4 mb_sel) */
- #define EQUL 2 /* Get rec that matches exactly (see dox) */
- #define FRST 3 /* Get the first record, sequentially */
- #define GTEQ 4 /* If not exact, get the one right after */
- #define GTHN 5 /* Like GTEQ, but won't accept exact one */
- #define LAST 6 /* Get the last record, sequentially */
- #define LTEQ 7 /* If not exact, get the one right before */
- #define LTHN 8 /* Like LTEQ, but won't accept exact one */
- #define NEXT 9 /* Get the next record, sequentially */
- #define PREV 10 /* Get the previous record, sequentially */
-
- #define CURRENT CURR /* These are included to reduce errors */
- #define EQUAL EQUL /* due to stupid humans who insist on */
- #define FIRST FRST /* using long words instead of short ones */
- #define GTHAN GTHN /* */
- #define LTHAN LTHN /* Gee, I'm considerate. */
- #define PREVIOUS PREV /* */
-
- #define ZEROES "\001\001\001\001\001\001\001\001\001\001\001\001."
-
- /****************************************************************************/
- /* */
- /* A reminder of the single rule that applies to EVERYTHING in this file: */
- /* */
- /* If you don't understand it, DON'T SCREW WITH IT. */
- /* */
- /* I'd like to emphasize that this rule is _most_important_ in viewing the */
- /* follow section of definitions. If you wanna change the internal */
- /* structure of the relations, and think you can (successfully, that is), */
- /* go right ahead. And send me a copy of the "better" MetalBase when you */
- /* think you're finished... I'd like to see it. (smiley-face) */
- /* */
- /****************************************************************************/
-
- #define _t_top(f,i) 4 + 4*i
- #define _idxs(f) 13*(_list[f].num_idx)
- #define _num_recs(f) 5 + 4*(_list[f].num_idx)
-
- #define _block(f) 11+(4*_list[f].num_idx)
- #define _base(f,r) _block(f)+_list[f].relbase+(r-1)*((13*_list[f].num_idx)+\
- 2+(_list[f].rec_len))
- #define _l_ptr(f,i,r) _base (f, r) + 13*i
- #define _r_ptr(f,i,r) _l_ptr (f, i, r) + 4
- #define _b_ptr(f,i,r) _r_ptr (f, i, r) + 4
- #define _rec(f,r) _base (f, r) + (13*_list[f].num_idx) + 1
-
- #define _len(f) 2 + _idxs (f) + _list[f].rec_len
-
- char buffer [BUF_LEN];
-
- extern int _Started;
-
- struct
- { long int pos, relbase;
- int relcode;
- int num_idx, rec_len;
- char alpha, beta, gamma;
-
- int idx_dups [20];
- int idx_just [MAX_FLDS];
- int idx_num [20][6];
- int idx_start [20][6];
- int idx_stop [20][5];
-
- char filename [80]; } _list [MAX_REL];
-
- /****************************************************************************/
-
- #define hash(a,o,g) ((a + o) & g)
-
- void breakkey (n, key)
- int n;
- int key;
- {
- _list[n].alpha = (key & 48) >> 4;
- _list[n].beta = (key & 63);
- _list[n].gamma = (key & 192) >> 6;
- }
-
- void _encrypt (temp, n)
- char *temp;
- int n;
- {
- register int len;
- char old;
-
- for (len = 0, old=_list[n].beta; temp[len] != 0; len++)
- old = temp[len] = 127 - temp[len] ^ hash (_list[n].alpha, old, _list[n].gamma);
- }
-
- void _decrypt (temp, n)
- char *temp;
- int n;
- {
- register int len;
- char old, oold;
-
- for (len = 0, old=_list[n].beta; temp[len] != 0; len++, old=oold)
- temp[len] = (127 - (oold = temp[len])) ^ hash (_list[n].alpha, old, _list[n].gamma);
- }
-
- _diff (one, two, use_sp, num)
- char *one, *two;
- int use_sp, num;
- {
- register int i;
- char lold, rold, l, r;
- int x, sp, vl, a, g;
-
- a = _list[num].alpha;
- lold = rold = _list[num].beta;
- g = _list[num].gamma;
-
- x = 0;
-
- do
- { vl = 0; sp = 1-use_sp;
-
- for (i = x; one[i] != 0 && one[i] != '|'; i++)
- { if (use_sp == 1 && one[i] != ' ') sp = 1;
-
- if (vl == 0)
- { l = (127 - (lold = one[i])) ^ hash (a, lold, g);
- r = (127 - (rold = two[i])) ^ hash (a, rold, g);
-
- if (l > r) vl = -1;
- if (l < r) vl = 1;
- };
-
- if (one[i] == '|') lold = rold = _list[num].beta;
- };
-
- if (sp != 0 && vl != 0) return vl;
-
- x = i+1;
- } while (one[i] != 0);
-
- return 0;
- }
-
- /****************************************************************************/
-
- char *repeat (ch, nm)
- int ch, nm;
- {
- char buf [MAX_RPT];
-
- buf[(nm = (nm < 0) ? 0 : nm)] = 0;
-
- for (nm--; nm >= 0; nm--) buf[nm] = ch;
-
- return buf;
- }
-
- char *_next_line (file)
- int file;
- {
- register int i;
- int j;
-
- j = 0;
-
- do i = read (file, &buffer[j++], 1);
- while (i != 0 && buffer[j-1] != '\n' && buffer[j-1] != 0);
-
- buffer[j-1] = 0;
-
- return buffer;
- }
-
- char *_rcd (file, rec)
- int file, rec;
- {
- static char temp[BUF_LEN];
-
- lseek (_list[file].relcode, _rec (file, rec), 0);
-
- read (_list[file].relcode, temp, _list[file].rec_len);
-
- temp[_list[file].rec_len] = 0;
-
- return temp;
- }
-
- char *_skey (file, index, str)
- int file, index;
- char *str;
- {
- register int j, s, i;
- static char temp[BUF_LEN];
-
- for (i = s = 0; _list[file].idx_start[index][i] != -1; i++)
- {
- for (j = _list[file].idx_start[index][i];
- j < _list[file].idx_stop [index][i]; j++) temp[s++] = str[j];
-
- temp[s++] = '|';
- };
-
- temp[s] = 0;
-
- return temp;
- }
-
- char *_key (file, index, rec)
- int file, index, rec;
- {
- static char temp[BUF_LEN];
-
- strcpy (temp, _skey (file, index, _rcd (file, rec)));
-
- return temp;
- }
-
- char *cut (str, num)
- char *str;
- int num;
- {
- static char buff [MAX_CUT];
-
- if (num == 0)
- sprintf (buff, "");
- else
- for (buff[num] = 0; num > 0; num--) buff[num-1] = str[num-1];
-
- return buff;
- }
-
- char *_spc (file, index, str, enc)
- int file, index, enc;
- char *str;
- {
- register int i, a;
- int x, b;
- static char temp[BUF_LEN];
-
- i = b = temp[0] = 0;
-
- do
- { x = (index == -1) ? b : _list[file].idx_num[index][b];
-
- if ((index == -1) ? (_list[file].idx_just[x] != 0) : (x != -1))
- { for (a = 0; str[i] != '|' && str[i] != 0; i++, a++);
-
- if (_list[file].idx_just[x] > 0)
- sprintf (buffer, "%s%s", repeat (' ', _list[file].idx_just[x]-a),
- cut (&str[i-a], a));
- else
- sprintf (buffer, "%s%s", cut (&str[i-a], a),
- repeat (' ', 0-_list[file].idx_just[x]-a));
-
- if (enc == -1) _decrypt (buffer, file);
- if (enc == 1) _encrypt (buffer, file);
-
- strcat (temp, buffer);
- strcat (temp, "|");
- };
-
- i = (str[i] == 0) ? i : i+1;
- b++;
- } while ((index == -1) ? (_list[file].idx_just[x] != 0) : (x != -1));
-
- return temp;
- }
-
- pattern (whole, match, skip)
- char *whole, *match;
- int skip;
- {
- int i, j, m, w;
-
- m = strlen (match); w = strlen (whole);
-
- for (i = 0; i <= w-m; i++)
- {
- for (j = 0; match [j] != 0 && whole[i+j] == match[j]; j++)
- ;
-
- if (match[j] == 0) if (skip-- == 0) return i;
- };
-
- return -1;
- }
-
- /* Encode and Eval perform base 10 to base 255 conversion, with a bottom
- value of 1 (As opposed to 0) for the base-255 numbers. Perfect for
- encoding BIG numbers (See chart) and storing them in 5 bytes on disk, eh?
-
- # of characters used______________Maximum integer representable
- 1 254
- 2 65024
- 3 16581374
- 4 4228250624
- 5 107820390900.... etc. */
-
- long _eval (st, x)
- char *st;
- int x;
- {
- long int j;
- long int n;
- int a;
-
- j = 0; n = 1;
-
- while (x > 0) { a = st[--x]; a = fix (a); j += n * (a - 1); n *= 255; };
-
- return j;
- }
-
- char *_encode (num, len)
- long int num;
- int len;
- {
- register int i;
- int a;
- static char buf[10];
-
- len = (len < 9) ? len : 9;
-
- for (i = len-1; i >= 0; i--)
- { a = num % 255;
-
- num = (num - a) / 255;
-
- buf[i] = a + 1;
- };
-
- buf[len] = 0;
-
- return buf;
- }
-
- mb_lck (file)
- int file;
- {
- if (file < 0 || file > MAX_REL) return INVALID_FILE_CODE;
- if (_list[file].pos == -1) return NOT_OPEN;
-
- lseek (_list[file].relcode, 0L, 0); read (_list[file].relcode, buffer, 1);
-
- if (fix (buffer[0]) == 127) return OKAY;
- if (fix (buffer[0]) != 2) return LOCK_DENIED;
-
- buffer[0] = 127;
-
- lseek (_list[file].relcode, 0L, 0); write (_list[file].relcode, buffer, 1);
-
- return OKAY;
- }
-
- mb_unl (file)
- int file;
- {
- if (file < 0 || file > MAX_REL) return INVALID_FILE_CODE;
- if (_list[file].pos == -1) return NOT_OPEN;
-
- lseek (_list[file].relcode, 0L, 0); read (_list[file].relcode, buffer, 1);
-
- if (buffer[0] != 127) return OKAY;
-
- buffer[0] = 2;
-
- lseek (_list[file].relcode, 0L, 0); write (_list[file].relcode, buffer, 1);
-
- return OKAY;
- }
-
- mb_rst (filename)
- char *filename;
- {
- int relcode;
-
- sprintf (buffer, "%s.rel", filename);
-
- if ((relcode = open (buffer, O_RDWR)) == -1)
- return CANNOT_OPEN_REL;
-
- if (read (relcode, buffer, 4) != 4)
- return CANNOT_READ_REL;
-
- sprintf (buffer, "%c", '\001');
-
- lseek (relcode, 0L, 0); write (relcode, buffer, 1);
-
- return OKAY;
- }
-
- mb_inc (filename, key)
- char *filename, key;
- {
- char temp[5];
- int i, place, relcode, n;
-
- place = -1;
-
- if (_Started == -1)
- { _Started = 0;
-
- for (i = 0; i < MAX_REL; i++) _list[i].pos = -1;
- };
-
- for (i = 0; i < MAX_REL; i++)
- if (_list[i].pos == -1)
- place = (place == -1) ? i : place;
-
- if (place == -1) return NOT_ENOUGH_ROOM;
-
- sprintf (buffer, "%s.rel", filename);
-
- if ((relcode = _list[place].relcode = open (buffer, O_RDWR)) == -1)
- return CANNOT_OPEN_REL;
-
- if (read (relcode, buffer, 4) != 4)
- return CANNOT_READ_REL;
-
- n = fix (buffer[0]);
-
- if (n == 121 || n == 249) return RELATION_BUSY;
- if (n == 127) return RELATION_LOCKED;
-
- sprintf (temp, "%c", n+1);
-
- lseek (relcode, 0L, 0); write (relcode, temp, 1);
-
- _list[place].num_idx = _eval (&buffer[1], 1);
- _list[place].rec_len = _eval (&buffer[2], 2);
-
- if (_fill_idx (place) == -1) return CORRUPT_INDEX;
-
- strcpy (_list[place].filename, filename);
-
- _list[place].pos = 0;
-
- breakkey (place, key);
-
- return place;
- }
-
- _fill_idx (file)
- int file;
- {
- register int j;
- int acc, i, k;
- char temp[BUF_LEN];
-
- acc = _list[file].relcode;
-
- _list[file].relbase = 0 - lseek (acc, _block(file), 0); _next_line (acc);
-
- for (i = 0; i < _list[file].num_idx; i++)
- { strcpy (temp, _next_line (acc));
-
- for (j = 0; temp[4*j] != 0 && temp[4*j] != 'd'; j++)
- _list[file].idx_num[i][j] = atoi (cut (&temp[4*j], 3)) - 1;
-
- _list[file].idx_num[i][j] = -1;
-
- _list[file].idx_dups[i] = (temp[4*j] == 'd') ? 1 : 0;
- };
-
- _list[file].relbase += lseek (acc, 0L, 1);
-
- lseek (acc, _block(file), 0);
-
- strcpy (temp, _next_line (acc));
-
- for (i = 0; i < _list[file].num_idx; i++)
- {
- for (k = 0; _list[file].idx_num[i][k] != -1; k++)
- { _list[file].idx_start[i][k] = 0;
-
- for (j = 0; j < _list[file].idx_num[i][k]; j++)
- _list[file].idx_start[i][k] += 1 + atoi (cut (&temp[5*j], 3));
-
- _list[file].idx_stop[i][k] = _list[file].idx_start[i][k] +
- atoi (cut (&temp[5*j], 3));
- };
-
- _list[file].idx_num[i][k] = _list[file].idx_start[i][k] = -1;
- };
-
- for (j = 0; temp[5*j] != 0; _list[file].idx_just[j] = ((temp[5*j+3] == 'r')
- ? atoi (cut (&temp[5*j], 3)) : (0 - atoi (cut(&temp[5*j], 3)))), j++);
-
- _list[file].idx_just[j] = 0;
-
- return OKAY;
- }
-
-
- mb_rmv (file)
- int file;
- {
- int n;
-
- if (file < 0 || file > MAX_REL) return INVALID_FILE_CODE;
- if (_list[file].pos == -1) return NOT_OPEN;
-
- _list[file].pos = -1;
-
- lseek (_list[file].relcode, 0L, 0); read (_list[file].relcode, buffer, 1);
- n=fix (buffer[0]); n=((n == 127) ? 1 : n-1); buffer[0]=((n < 1) ? 1 : n);
- lseek (_list[file].relcode, 0L, 0); write (_list[file].relcode, buffer, 1);
-
- close (_list[file].relcode);
-
- return OKAY;
- }
-
- mb_upd (file, string)
- int file;
- char *string;
- {
- register int i;
- long int pos;
- int acc;
- char temp[BUF_LEN];
-
- strcpy (buffer, _spc (file, -1, string, 1));
-
- if (file < 0 || file > MAX_REL) return INVALID_FILE_CODE;
- if (_list[file].pos == -1) return NOT_OPEN;
- if ((pos = _list[file].pos) == 0) return NO_CURRENT_RECORD;
- if (strlen (buffer) != _list[file].rec_len) return RCD_INVALID;
-
- if (_set_lck ((acc = _list[file].relcode), 1) != 0) return RELATION_HUNG;
-
- for (i = 0; i < _list[file].num_idx; i++)
- { if (_list[file].idx_dups[i] == 0)
- { strcpy (temp, _skey (file, i, buffer));
-
- if (_search (file, i, EQUL, temp, _find_top (file, i)) != 0)
- { _clr_lck (acc);
-
- return ILLEGAL_DUPLICATE;
- };
- };
- };
-
- lseek (acc, _rec (file, pos), 0); read (acc, temp, _list[file].rec_len);
- lseek (acc, _rec (file, pos), 0); write (acc, buffer, _list[file].rec_len);
-
- for (i = 0; i < _list[file].num_idx; i++)
- { _disconnect (file, i, pos);
- _drop (file, i, pos);
- };
-
- _clr_lck (acc);
-
- return OKAY;
- }
-
- mb_add (file, string)
- int file;
- char *string;
- {
- register int i;
- int r_o, acc;
- char temp[BUF_LEN], tmp2[5];
-
- strcpy (buffer, _spc (file, -1, string, 1));
-
- if (file < 0 || file > MAX_REL) return INVALID_FILE_CODE;
- if (_list[file].pos == -1) return NOT_OPEN;
- if (strlen (buffer) != _list[file].rec_len) return RCD_INVALID;
-
- if (_set_lck ((acc = _list[file].relcode), 1) != 0) return RELATION_HUNG;
-
- for (i = 0; i < _list[file].num_idx; i++)
- { if (_list[file].idx_dups[i] == 0)
- { strcpy (temp, _skey (file, i, buffer));
-
- if (_search (file, i, EQUL, temp, _find_top (file, i)) != 0)
- { _clr_lck (acc);
-
- return ILLEGAL_DUPLICATE;
- };
- };
- };
-
- lseek (acc, _num_recs(file), 0); read (acc, tmp2, 4);
-
- r_o = _eval (tmp2, 4) + 1;
-
- lseek (acc, _base (file, r_o), 0);
-
- for (i = 0; i < _list[file].num_idx; i++) write (acc, ZEROES, 13);
-
- write (acc, "\n", 1);
- write (acc, buffer, _list[file].rec_len);
- write (acc, "\n", 1);
-
- for (i = 0; i < _list[file].num_idx; i++) _drop (file, i, r_o);
-
- lseek (acc, _num_recs (file), 0); write (acc, _encode (r_o, 4), 4);
-
- _clr_lck (acc);
-
- return OKAY;
- }
-
- long _find_top (file, index)
- int file, index;
- {
- char temp [5];
-
- lseek (_list[file].relcode, _t_top (file, index), 0);
- read (_list[file].relcode, temp, 4);
-
- return (_eval (temp, 4));
- }
-
- _drop (file, index, rec)
- int file, index, rec;
- {
- int acc, a, off;
- char temp [BUF_LEN];
- char temp2 [14];
-
- acc = _list[file].relcode;
- off = a = _find_top (file, index);
-
- if (a == 0)
- { lseek (acc, _t_top (file, index), 0);
- write (acc, _encode (rec, 4), 4); }
- else
- { strcpy (temp, _key (file, index, rec));
-
- do
- { off = a;
-
- lseek (acc, _l_ptr (file, index, off), 0); read (acc, temp2, 8);
-
- if (_diff (_key (file, index, off), temp, 0, file) == -1)
- { if ((a = _eval (&temp2[0], 4)) == 0)
- sprintf (temp2, "%-4.4s%-4.4s", _encode (rec, 4), &temp2[4]);
- }
- else
- { if ((a = _eval (&temp2[4], 4)) == 0)
- sprintf (temp2, "%-4.4s%-4.4s", temp2, _encode (rec, 4));
- };
- } while (a != 0);
-
- lseek (acc, _l_ptr (file, index, off), 0); write (acc, temp2, 8);
- };
-
- sprintf (temp, "%-8.8s%-4.4s", ZEROES, _encode (off, 4));
-
- lseek (acc, _l_ptr (file, index, rec), 0); write (acc, temp, 12);
-
- return;
- }
-
- mb_sel (file, index, str, action, comp)
- int file, index, action;
- char *str, *comp;
- {
- long off;
-
- if (file < 0 || file > MAX_REL) return INVALID_FILE_CODE;
- if (_list[file].pos == -1) return NOT_OPEN;
- if (_set_lck (_list[file].relcode, 0) != 0) return RELATION_HUNG;
- if (action != CURRENT)
- if (index < 1 || index > _list[file].num_idx) return INVALID_INDEX;
-
- strcpy (buffer, (comp[0] == 0) ? "" : _spc (file, index-1, comp, 1));
-
- if (_list[file].pos == 0)
- { if (action == NEXT) action = FRST;
- if (action == PREV) action = LAST;
- };
-
- switch (action)
- { case FRST:
- case LAST: off = _get_ends (file, index-1, action);
- break;
- case CURR: off = _list[file].pos;
- break;
- case NEXT:
- case PREV: off = _get_sides (file, index-1, action);
- break;
- case GTEQ:
- case GTHN:
- case LTEQ:
- case LTHN:
- case EQUL: off = _search (file, index-1, action, buffer,
- _find_top (file, index-1));
- break;
- default : return UNKNOWN_ACTION;
- };
-
- if (off == 0) return NOT_FOUND;
- if (off < 0) return off;
-
- strcpy (str, _spc (file, -1, _rcd (file, (_list[file].pos = off)), -1));
-
- return OKAY;
- }
-
- _get_ends (file, index, action)
- int file, index, action;
- {
- long go, off;
- int acc;
- char buf[10];
-
- acc = _list[file].relcode;
-
- if ((go = off = _find_top (file, index)) == 0) return NOT_FOUND;
-
- while (go != 0)
- { lseek (acc, _l_ptr (file, index, off), 0); read (acc, buf, 8);
-
- off = ((go = _eval (&buf[(action == LAST) ? 4 : 0], 4)) == 0) ? off : go;
- };
-
- return off;
- }
-
- _get_sides (file, index, action)
- int file, index, action;
- {
- long pos;
- int acc, same, go, off;
- char buf[13];
-
- acc = _list[file].relcode;
- pos = _list[file].pos;
-
- same = (action == NEXT) ? 4 : 0;
-
- lseek (acc, _l_ptr (file, index, pos), 0); read (acc, buf, 12);
-
- if ((go = off = _eval (&buf[same], 4)) == 0)
- { go = pos;
-
- for (;;)
- { if ((off = _eval (&buf[8], 4)) == 0) return NOT_FOUND;
-
- lseek (acc, _l_ptr (file, index, off), 0); read (acc, buf, 12);
-
- if (go == _eval (&buf[4-same], 4)) return off;
-
- go = off;
- };
- };
-
- while (go != 0)
- { lseek (acc, _l_ptr (file, index, off), 0); read (acc, buf, 8);
-
- off = ((go = _eval (&buf[4-same], 4)) == 0) ? off : go;
- };
-
- return off;
- }
-
- _search (file, index, action, comp, pos)
- int file, index, action, pos;
- char *comp;
- {
- long x;
- int flag, r, dir;
- char temp[9];
-
- if (pos == 0) return 0;
-
- lseek (_list[file].relcode, _l_ptr (file, index, pos), 0);
-
- read (_list[file].relcode, temp, 8);
-
- flag = ((r = _diff (comp, _key (file, index, pos), 1, file)) == 0) ? 1 : 0;
-
- if (r == -1) dir = 4;
- if (r == 1) dir = 0;
- if (r == 0)
- { if (action == GTHN || action == LTEQ) dir = 4;
- if (action == GTEQ || action == LTHN || action == EQUL) dir = 0;
- };
-
- if ((x = _search (file, index, action, comp, _eval (&temp[dir], 4))) != 0)
- return x;
-
- if (action != GTHN && action != LTHN && flag == 1) return pos;
- if ((action == GTEQ || action == GTHN) && dir == 0) return pos;
- if ((action == LTEQ || action == LTHN) && dir == 4) return pos;
-
- return 0;
- }
-
- mb_del (file, verify) /* 'verify' is ignored--only used so programs won't */
- int file, verify; /* compile if mb_del is confused with mb_rmv */
- {
- long int to_die, last, pos;
- int i, acc;
- char temp[13], sidx[13];
-
- if (file < 0 || file > MAX_REL) return INVALID_FILE_CODE;
- if (_list[file].pos == -1) return NOT_OPEN;
-
- lseek ((acc = _list[file].relcode), _num_recs (file), 0);
- read (acc, temp, 4);
-
- if ((to_die = _list[file].pos) <= 0) return NO_CURRENT_RECORD;
- if ((last = _eval (temp, 4)) == 0) return NO_CURRENT_RECORD;
- if (_set_lck (acc, 1) != 0) return RELATION_HUNG;
-
- for (i = 0; i < _list[file].num_idx; i++) _disconnect (file, i, to_die);
-
- if (last != to_die)
- { lseek (acc, _base (file, last), 0); read (acc, buffer, _len (file));
- lseek (acc, _base (file, to_die), 0); write (acc, buffer, _len (file));
-
- strcpy (sidx, _encode (to_die, 4));
-
- for (i = 0; i < _list[file].num_idx; i++)
- { if ((pos = _eval (&buffer[13*i+8], 4)) == 0)
- lseek (acc, _t_top (file, i), 0);
- else
- { lseek (acc, _l_ptr (file, i, pos), 0); read (acc, temp, 4);
-
- if (_eval (temp, 4) == last) lseek (acc, -4L, 1);
- };
- write (acc, sidx, 4);
-
- if ((pos = _eval (&buffer[13*i], 4)) != 0)
- { lseek (acc, _b_ptr (file, i, pos), 0); write (acc, sidx, 4); };
- if ((pos = _eval (&buffer[13*i+4], 4)) != 0)
- { lseek (acc, _b_ptr (file, i, pos), 0); write (acc, sidx, 4); };
- };
- };
-
- strcpy (temp, _encode (last-1, 4));
-
- lseek (acc, _num_recs (file), 0); write (acc, temp, 4);
-
- _clr_lck (acc);
-
- _list[file].pos = 0;
-
- return OKAY;
- }
-
- _move (file, i, self, targ, child, dad, dch, dir, sidx)
- int file, i, dch, dir;
- long self, targ, child, dad;
- char *sidx;
- {
- long int pos;
- int acc;
- char temp[13], ltgt[5];
-
- acc = _list[file].relcode;
-
- sprintf (temp, "%-12.12s", sidx);
-
- if (dch == 1)
- change (&temp[dir], _encode (child, 4), 4);
- else
- { if (child != 0)
- { lseek (acc, _b_ptr (file, i, child), 0);
- write (acc, _encode (dad, 4), 4);
- };
-
- if (dad != 0) lseek (acc, _l_ptr (file, i, dad) + 4 - dir, 0);
- else lseek (acc, _t_top (file, i), 0);
-
- write (acc, _encode (child, 4), 4);
- };
-
- lseek (acc, _l_ptr (file, i, targ), 0); write (acc, temp, 12);
-
- if ((pos = _eval (&temp[8], 4)) == 0)
- lseek (acc, _t_top (file, i), 0);
- else
- { lseek (acc, _l_ptr (file, i, pos), 0); read (acc, ltgt, 4);
-
- if (_eval (ltgt, 4) == self) lseek (acc, -4L, 1);
- };
-
- strcpy (ltgt, _encode (targ, 4)); write (acc, ltgt, 4);
-
- if ((pos = _eval (&temp[0], 4)) != 0)
- { lseek (acc, _b_ptr (file, i, pos), 0); write (acc, ltgt, 4); };
-
- if ((pos = _eval (&temp[4], 4)) != 0)
- { lseek (acc, _b_ptr (file, i, pos), 0); write (acc, ltgt, 4); };
- }
-
- _disconnect (file, i, to_die)
- int file, i;
- long int to_die;
- {
- int acc;
- int level_n, dch_n, level_p, dch_p;
- long int rch, pos, targ_n, targ_p, lch;
- long int dad_n, dad_p;
- char sidx[13], temp[13];
-
- acc = _list[file].relcode;
-
- lseek (acc, _l_ptr (file, i, to_die), 0); read (acc, sidx, 12);
-
- level_n = level_p = 0;
-
- for (pos = targ_n = _eval (&sidx[4], 4); pos != 0; level_n++)
- { lseek (acc, _l_ptr (file, i, pos), 0); read (acc, temp, 4);
-
- targ_n = pos; pos = _eval (temp, 4);
- };
-
- if (level_n != 0)
- { lseek (acc, _l_ptr (file, i, targ_n), 0); read (acc, temp, 12);
-
- rch = _eval (&temp[4], 4);
- dad_n = _eval (&temp[8], 4);
- dch_n = (level_n == 1) ? 1 : 0;
-
- for (pos = rch; pos != 0; level_n++)
- { lseek (acc, _r_ptr (file, i, pos), 0); read (acc, temp, 4);
-
- pos = _eval (temp, 4);
- };
- };
-
- for (pos = targ_p = _eval (&sidx[0], 4); pos != 0; level_p++)
- { lseek (acc, _r_ptr (file, i, pos), 0); read (acc, temp, 4);
-
- targ_p = pos; pos = _eval (temp, 4);
- };
-
- if (level_p != 0)
- { lseek (acc, _l_ptr (file, i, targ_p), 0); read (acc, temp, 12);
-
- lch = _eval (&temp[0], 4);
- dad_p = _eval (&temp[8], 4);
- dch_p = (level_p == 1) ? 1 : 0;
-
- for (pos = lch; pos != 0; level_p++)
- { lseek (acc, _l_ptr (file, i, pos), 0); read (acc, temp, 4);
-
- pos = _eval (temp, 4);
- };
- };
-
- if (level_n == 0 && level_p == 0)
- { if ((pos = _eval (&sidx[8], 4)) == 0)
- lseek (acc, _t_top (file, i), 0);
- else
- { lseek (acc, _l_ptr (file, i, pos), 0); read (acc, temp, 4);
-
- if (_eval (temp, 4) == to_die) lseek (acc, -4L, 1);
- };
-
- write (acc, ZEROES, 4);
- }
- else
- { if (level_n >= level_p)
- _move (file, i, to_die, targ_n, rch, dad_n, dch_n, 4, sidx);
- else
- _move (file, i, to_die, targ_p, lch, dad_p, dch_p, 0, sidx);
- };
- }
-
- _clr_lck (acc)
- int acc;
- {
- char t[3];
- int n;
-
- lseek (acc, 0L, 0); read (acc, t, 1);
- n = fix (t[0]); n = ((n > 127) ? (n-127) : n); t[0] = n;
- lseek (acc, 0L, 0); write (acc, t, 1);
- }
-
- _set_lck (acc, set)
- int acc, set;
- {
- char t[3];
- int n;
- register int i;
-
- n = 0;
-
- do
- { lseek (acc, 0L, 0); read (acc, t, 1);
-
- if (fix (t[0]) > 127)
- { if (n == 200) return -1;
-
- for (i = 0, n++; i < 6000; i++);
- };
- } while (fix (t[0]) > 127);
-
- if (set == 1)
- { sprintf (t, "%c", fix (t[0]) + 127);
-
- lseek (acc, 0L, 0); write (acc, t, 1);
- };
-
- return 0;
- }
-
- change (one, two, num)
- char *one, *two;
- int num;
- {
- register int i;
-
- for (i = num-1; i >= 0; i--) one[i] = two[i];
- }
-
-