/* ******************************************************************** * *** 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]; }