| version 1.14, 2025/04/09 19:52:02 | version 1.21, 2025/04/11 20:55:49 | 
| Line 24 | Line 24 | 
 | *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>. | *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>. | 
 | * | * | 
 | *   $Log$ | *   $Log$ | 
 |  | *   Revision 1.21  2025/04/11 20:55:49  snw | 
 |  | *   Disable -Wunused-result where possible | 
 |  | * | 
 |  | *   Revision 1.20  2025/04/11 18:24:32  snw | 
 |  | *   Fix bug in memory cache | 
 |  | * | 
 |  | *   Revision 1.19  2025/04/11 16:52:05  snw | 
 |  | *   Fix indentation in global handler | 
 |  | * | 
 |  | *   Revision 1.18  2025/04/11 16:23:18  snw | 
 |  | *   Avoid re-reading the same block consecutively when possible | 
 |  | * | 
 |  | *   Revision 1.17  2025/04/11 14:21:03  snw | 
 |  | *   Make all but one of the read/write calls in global_bltin use gbl_read_block or gbl_write_block | 
 |  | * | 
 |  | *   Revision 1.16  2025/04/11 00:52:40  snw | 
 |  | *   Replace all lseek/read calls in global handler to use gbl_read_block function | 
 |  | * | 
 |  | *   Revision 1.15  2025/04/10 01:24:38  snw | 
 |  | *   Remove C++ style comments | 
 |  | * | 
 | *   Revision 1.14  2025/04/09 19:52:02  snw | *   Revision 1.14  2025/04/09 19:52:02  snw | 
 | *   Eliminate as many warnings as possible while building with -Wall | *   Eliminate as many warnings as possible while building with -Wall | 
 | * | * | 
| Line 78  global_handle *global_handles_head; | Line 99  global_handle *global_handles_head; | 
 | unsigned long gbl_cache_misses = 0; | unsigned long gbl_cache_misses = 0; | 
 | unsigned long gbl_cache_hits = 0; | unsigned long gbl_cache_hits = 0; | 
 |  |  | 
| static void b_free (short filedes, unsigned long blknbr); | static void b_free (global_handle *g, unsigned long blknbr); | 
 | static void splitp (global_handle *g, char *block, long *addr, long *offs, unsigned long *blknbr); | static void splitp (global_handle *g, char *block, long *addr, long *offs, unsigned long *blknbr); | 
 | static void update (global_handle *g, char *ins_key, long keyl); | static void update (global_handle *g, char *ins_key, long keyl); | 
 | static void insert (global_handle *g, char *ins_key, long key_len, unsigned long blknbr); | static void insert (global_handle *g, char *ins_key, long key_len, unsigned long blknbr); | 
 | static void scanpblk (char *block, long *adr, long *fnd); | static void scanpblk (char *block, long *adr, long *fnd); | 
 | static void scandblk (char *block, long *adr, long *fnd); | static void scandblk (char *block, long *adr, long *fnd); | 
| static void getnewblk (int filedes, unsigned long *blknbr); | static void getnewblk (global_handle *g, unsigned long *blknbr); | 
 | static short int g_collate (char *t); | static short int g_collate (char *t); | 
 | //static short int g_numeric (char *str); |  | 
 | short g_numeric (char *str); | short g_numeric (char *str); | 
 | void close_all_globals(void); | void close_all_globals(void); | 
 | static void panic (void); | static void panic (void); | 
| Line 131  static void panic (void); | Line 151  static void panic (void); | 
 | #define DATA     8 | #define DATA     8 | 
 |  |  | 
 | #if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) && !defined(__OS2__) | #if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) && !defined(__OS2__) | 
| long time (); | long time (); | 
 | #endif | #endif | 
 |  |  | 
 | inline long gbl_path(char *key, char *buf) | inline long gbl_path(char *key, char *buf) | 
| Line 314  int gbl_write_header(global_handle *g, g | Line 334  int gbl_write_header(global_handle *g, g | 
 | if (g->opened == FALSE) { | if (g->opened == FALSE) { | 
 | return FALSE; | return FALSE; | 
 | } | } | 
|  |  | 
 | gbl_lock (g, 1); | gbl_lock (g, 1); | 
 | old_position = lseek (g->fd, 0, SEEK_CUR); | old_position = lseek (g->fd, 0, SEEK_CUR); | 
 | lseek (g->fd, 0, SEEK_SET); | lseek (g->fd, 0, SEEK_SET); | 
| Line 437  short gbl_open(global_handle *g, short a | Line 457  short gbl_open(global_handle *g, short a | 
 | } | } | 
 | else { | else { | 
 | g->opened = TRUE; | g->opened = TRUE; | 
| result = gbl_read_header (g, &g->header); | result = gbl_read_header (g, &g->header); | 
 |  |  | 
 | if (result == GBL_HDR_OK) { | if (result == GBL_HDR_OK) { | 
 |  | /* initialize last_block_accessed cache */ | 
 |  | g->last_block_accessed = (char *) calloc (g->header.block_size, sizeof (char)); | 
 |  | NULLPTRCHK(g->last_block_accessed,"gbl_open"); | 
 |  |  | 
 | g->opened = TRUE; | g->opened = TRUE; | 
 | } | } | 
 | else { | else { | 
| Line 469  short gbl_open(global_handle *g, short a | Line 493  short gbl_open(global_handle *g, short a | 
 |  |  | 
 | } /* gbl_open() */ | } /* gbl_open() */ | 
 |  |  | 
 |  | int gbl_read_block(global_handle *g, unsigned long blocknum, char *block) | 
 |  | { | 
 |  | struct stat gstat; | 
 |  | unsigned long hdr_offset; | 
 |  | hdr_offset = sizeof (global_header); | 
 |  |  | 
 |  | if (g->opened == FALSE) { | 
 |  | return FALSE; | 
 |  | } | 
 |  |  | 
 |  | g->use_count++; | 
 |  |  | 
 |  | if (!g->locked) gbl_lock (g, 1); | 
 |  | fstat (g->fd, &gstat); | 
 |  |  | 
 |  | if ((g->last_block == blocknum) && | 
 |  | (g->have_cached_block) && | 
 |  | (g->cached_block_num == blocknum) && | 
 |  | (gstat.st_mtime < g->last_read_time)) { | 
 |  | /* the global has not been modified since the last read; grab from memory */ | 
 |  | g->memory_reads++; | 
 |  | memcpy (block, g->last_block_accessed, g->header.block_size); | 
 |  | } | 
 |  | else { | 
 |  | /* have to go out to disk */ | 
 |  | lseek (g->fd, hdr_offset + ((long) blocknum * (long) (g->header.block_size)), SEEK_SET); | 
 |  | read (g->fd, block, g->header.block_size); | 
 |  |  | 
 |  | /* update cache */ | 
 |  | memcpy (g->last_block_accessed, block, g->header.block_size); | 
 |  | g->have_cached_block = TRUE; | 
 |  | g->cached_block_num = blocknum; | 
 |  | g->last_block = blocknum; | 
 |  | g->read_ops++; | 
 |  | } | 
 |  |  | 
 |  | g->last_read_time = time (0L); | 
 |  | g->use_count++; | 
 |  |  | 
 |  | if (g->locked) gbl_unlock (g); | 
 |  |  | 
 |  | return TRUE; | 
 |  | } /* gbl_read_block() */ | 
 |  |  | 
 |  | int gbl_write_block(global_handle *g, unsigned long blocknum, char *block) | 
 |  | { | 
 |  | int errsav; | 
 |  | unsigned long hdr_offset; | 
 |  | hdr_offset = sizeof (global_header); | 
 |  |  | 
 |  | if (g->opened == FALSE) { | 
 |  | return FALSE; | 
 |  | } | 
 |  |  | 
 |  | gbl_lock (g, 1); | 
 |  |  | 
 |  | for (;;) { | 
 |  |  | 
 |  | errno = 0; | 
 |  |  | 
 |  | lseek (g->fd, hdr_offset + (blocknum * g->header.block_size), SEEK_SET); | 
 |  | write (g->fd, block, BLOCKLEN); | 
 |  | errsav = errno; | 
 |  | g->last_block = blocknum; | 
 |  | g->use_count++; | 
 |  | g->write_ops++; | 
 |  |  | 
 |  | if (errsav == 0) break; | 
 |  |  | 
 |  | panic (); | 
 |  |  | 
 |  | } | 
 |  |  | 
 |  | gbl_update_tid (g); | 
 |  | gbl_unlock (g); | 
 |  |  | 
 |  | return TRUE; | 
 |  | } | 
 |  |  | 
 | global_handle *gbl_handle(char *key) | global_handle *gbl_handle(char *key) | 
 | { | { | 
 | global_handle *g; | global_handle *g; | 
| Line 510  global_handle *gbl_handle(char *key) | Line 613  global_handle *gbl_handle(char *key) | 
 | g->use_count = 1; | g->use_count = 1; | 
 | g->locked = FALSE; | g->locked = FALSE; | 
 | g->age = time (0L); | g->age = time (0L); | 
 |  | g->last_read_time = 0; | 
 | g->last_block = 0; | g->last_block = 0; | 
 | g->opened = FALSE; | g->opened = FALSE; | 
 | g->fd = 0; | g->fd = 0; | 
 | g->fast_path = -1; | g->fast_path = -1; | 
 | g->cache_misses = 0; | g->cache_misses = 0; | 
 | g->cache_hits = 0; | g->cache_hits = 0; | 
 |  | g->read_ops = 0; | 
 |  | g->write_ops = 0; | 
 |  | g->memory_reads = 0; | 
 |  | g->have_cached_block = FALSE; | 
 |  | g->last_block_accessed = NULL; | 
 |  |  | 
 | strcpy (g->global_name, global_name); | strcpy (g->global_name, global_name); | 
 | gbl_path (key, g->global_path); | gbl_path (key, g->global_path); | 
| Line 634  void global_bltin (short action, char *k | Line 743  void global_bltin (short action, char *k | 
 | static char block[BLOCKLEN]; | static char block[BLOCKLEN]; | 
 | static int getnflag;                /* flag 1=$ZO-variable 0=$Q-function */ | static int getnflag;                /* flag 1=$ZO-variable 0=$Q-function */ | 
 | static int tryfast;                 /* try fast access if get_sym on    */ | static int tryfast;                 /* try fast access if get_sym on    */ | 
| /* previous global */ | /* previous global */ | 
 |  |  | 
 | int iresult; | int iresult; | 
 |  |  | 
| Line 643  void global_bltin (short action, char *k | Line 752  void global_bltin (short action, char *k | 
 | register long int k; | register long int k; | 
 | register long int ch; | register long int ch; | 
 |  |  | 
 |  | j = 0; | 
 | hdr_offset = sizeof (global_header); | hdr_offset = sizeof (global_header); | 
 |  |  | 
 | /* process optional limitations */ | /* process optional limitations */ | 
 | if (glvnflag.all && key[0] >= '%' && key[0] <= 'z') { | if (glvnflag.all && key[0] >= '%' && key[0] <= 'z') { | 
 |  |  | 
 | if ((i = glvnflag.one[0])) {    /* number of significant chars */ | if ((i = glvnflag.one[0])) {    /* number of significant chars */ | 
 |  |  | 
 | j = 0; | j = 0; | 
 | while ((k = key[j]) != DELIM && k != EOL) { | while ((k = key[j]) != DELIM && k != EOL) { | 
 |  |  | 
 | if (j >= i) { | if (j >= i) { | 
 |  |  | 
 | while ((k = key[++j]) != DELIM && k != EOL); | while ((k = key[++j]) != DELIM && k != EOL); | 
 |  |  | 
 | stcpy (&key[i], &key[j]); | stcpy (&key[i], &key[j]); | 
 |  |  | 
 | break; | break; | 
 | } | } | 
 |  |  | 
 | j++; | j++; | 
 |  |  | 
 | } | } | 
 | } | } | 
 |  |  | 
 | if (glvnflag.one[1]) {          /* upper/lower sensitivity */ | if (glvnflag.one[1]) {          /* upper/lower sensitivity */ | 
 |  |  | 
 | j = 0; | j = 0; | 
 |  |  | 
 | while ((k = key[j]) != DELIM && k != EOL) { | while ((k = key[j]) != DELIM && k != EOL) { | 
 |  |  | 
 | if (k >= 'a' && k <= 'z') key[j] = k - 32; | if (k >= 'a' && k <= 'z') key[j] = k - 32; | 
 |  |  | 
 | j++; | j++; | 
 |  |  | 
 | } | } | 
 |  |  | 
 | } | } | 
 |  |  | 
 | if ((i = glvnflag.one[2])) { | if ((i = glvnflag.one[2])) { | 
 |  |  | 
 | if (stlen (key) > i) { | if (stlen (key) > i) { | 
 | merr_raise (M75); | merr_raise (M75); | 
 | return; | return; | 
 | }                           /* key length limit */ | }                           /* key length limit */ | 
 |  |  | 
 | } | } | 
 |  |  | 
 | if ((i = glvnflag.one[3])) {    /* subscript length limit */ | if ((i = glvnflag.one[3])) {    /* subscript length limit */ | 
|  |  | 
 | j = 0; | j = 0; | 
 |  |  | 
 | while ((k = key[j++]) != DELIM && k != EOL); | while ((k = key[j++]) != DELIM && k != EOL); | 
|  |  | 
 | if (k == DELIM) { | if (k == DELIM) { | 
 |  |  | 
 | k = 0; | k = 0; | 
 | for (;;) { | for (;;) { | 
 |  |  | 
 | k = key[j++]; | k = key[j++]; | 
 |  |  | 
 | if (k == DELIM || k == EOL) { | if (k == DELIM || k == EOL) { | 
 |  |  | 
 | if (k > i) { | if (k > i) { | 
 | merr_raise (M75); | merr_raise (M75); | 
 | return; | return; | 
 | } | } | 
 |  |  | 
 | k = 0; | k = 0; | 
 | } | } | 
 |  |  | 
 | if (k == EOL) break; | if (k == EOL) break; | 
 |  |  | 
 | k++; | k++; | 
 | } | } | 
 | } | } | 
 |  |  | 
 | } | } | 
 | } | } | 
 |  |  | 
| Line 780  void global_bltin (short action, char *k | Line 870  void global_bltin (short action, char *k | 
 | } | } | 
 | } | } | 
 |  |  | 
 | if (v22ptr) { |  | 
 |  |  | 
 | procv22 (key); |  | 
 |  |  | 
 | if (key[0] != '^') { |  | 
 | char    losav[256]; |  | 
 |  |  | 
 | stcpy (losav, l_o_val); |  | 
 | symtab (action, key, data); |  | 
 | stcpy (g_o_val, l_o_val); |  | 
 | stcpy (l_o_val, losav); |  | 
 |  |  | 
 | return; |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | g = gbl_handle (key); | g = gbl_handle (key); | 
 | i = gbl_path (key, filnam); | i = gbl_path (key, filnam); | 
 |  |  | 
| Line 860  void global_bltin (short action, char *k | Line 934  void global_bltin (short action, char *k | 
 | compactkey[k++] = ch << 1; | compactkey[k++] = ch << 1; | 
 |  |  | 
 | } | } | 
| else if (ch < SP || ch >= DEL) { | else if (ch < SP || ch >= DEL) { | 
|  | /* no CTRLs */ | 
| /*no CTRLs */ |  | 
|  |  | 
 | merr_raise (SBSCR); | merr_raise (SBSCR); | 
 | return; | return; | 
 | } | } | 
| Line 1007  reopen: | Line 1079  reopen: | 
 | merr_raise (iresult); | merr_raise (iresult); | 
 | return; | return; | 
 | } | } | 
 |  |  | 
 | for (;;) { |  | 
 |  |  | 
 | errno = 0; |  | 
 |  |  | 
 | lseek (g->fd, hdr_offset + (ROOT * BLOCKLEN), SEEK_SET); |  | 
 | write (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | if (errno == 0) break; |  | 
 |  |  | 
 | panic (); |  | 
 | } |  | 
 |  |  | 
 |  | gbl_write_block (g, ROOT, block); | 
 |  |  | 
 | block[NRBLK] = 0; | block[NRBLK] = 0; | 
 | block[NRBLK + 1] = 0; | block[NRBLK + 1] = 0; | 
 | block[NRBLK + 2] = ROOT;        /* clear */ | block[NRBLK + 2] = ROOT;        /* clear */ | 
| Line 1056  reopen: | Line 1118  reopen: | 
 | /* even ones read/write access          (set_sym,kill_sym)   1 */ | /* even ones read/write access          (set_sym,kill_sym)   1 */ | 
 |  |  | 
 | /* temporarily disabled | /* temporarily disabled | 
| lock: | lock: | 
 | */ | */ | 
 |  |  | 
 | if (action == get_sym) { | if (action == get_sym) { | 
| Line 1072  tfast0: | Line 1134  tfast0: | 
 |  |  | 
 |  |  | 
 | tfast1: | tfast1: | 
|  | gbl_read_block (g, blknbr, block); | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); |  | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | /* temporarily disabled | /* temporarily disabled | 
| tfast2: | tfast2: | 
 | */ | */ | 
| if ((typ = block[BTYP]) == DATA) {      /* scan data block: here we test for equality only */ | if ((typ = block[BTYP]) == DATA) {  /* scan data block: here we test for equality only */ | 
 |  |  | 
| offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
| j = UNSIGN (block[0]); | j = UNSIGN (block[0]); | 
| i = 0; | i = 0; | 
|  |  | 
| stcpy0 (key1, &block[2], j);        /* get first key */ |  | 
|  |  | 
| ch = keyl;          /* ch is a register! */ |  | 
|  |  | 
| while (i < offset) { |  | 
|  |  | 
| j = UNSIGN (block[i++]);        /* length of key - offset */ |  | 
| k = UNSIGN (block[i++]);        /* offset into previous entry */ |  | 
 |  |  | 
| j += k; | stcpy0 (key1, &block[2], j);    /* get first key */ | 
 |  |  | 
| while (k < j) key1[k++] = block[i++];           /* get key */ | ch = keyl;              /* ch is a register! */ | 
|  |  | 
| if (j != ch) {  /* keys have different length */ | while (i < offset) { | 
|  |  | 
|  | j = UNSIGN (block[i++]);    /* length of key - offset */ | 
|  | k = UNSIGN (block[i++]);    /* offset into previous entry */ | 
|  |  | 
|  | j += k; | 
|  |  | 
|  | while (k < j) key1[k++] = block[i++];               /* get key */ | 
|  |  | 
|  | if (j != ch) {      /* keys have different length */ | 
|  |  | 
|  | i += UNSIGN (block[i]); | 
|  | i++; | 
|  |  | 
|  | continue; | 
|  |  | 
|  | } | 
|  |  | 
|  | j = ch; | 
|  |  | 
|  | do { | 
|  | j--; | 
|  | } while (compactkey[j] == key1[j]);         /* compare keys */ | 
|  |  | 
|  |  | 
|  | if (j < 0) { | 
|  |  | 
|  | k = UNSIGN (block[i++]); | 
|  | stcpy0 (data, &block[i], k);    /* get value */ | 
|  | data[k] = EOL1; /* append EOL */ | 
|  |  | 
|  | goto quit; | 
|  |  | 
|  | } | 
 |  |  | 
 | i += UNSIGN (block[i]); | i += UNSIGN (block[i]); | 
| i++; | i++;                /* skip data */ | 
|  |  | 
| continue; | } | 
|  |  | 
|  | /* fast access failed. try normal path */ | 
|  | if (tryfast) { | 
|  | gbl_cache_miss (g); | 
|  | goto tfast0; | 
 | } | } | 
 |  |  | 
| j = ch; | merr_raise (M7); | 
|  | data[0] = EOL; | 
 |  |  | 
| do { | goto quit;              /* variable not found */ | 
| j--; | } | 
| } while (compactkey[j] == key1[j]);             /* compare keys */ | else { | 
 |  |  | 
|  | if (g->fast_path > 0) { | 
| if (j < 0) { | gbl_cache_miss (g); | 
|  | goto tfast0; | 
|  | } | 
|  |  | 
|  | if (typ == EMPTY) { | 
 |  |  | 
| k = UNSIGN (block[i++]); | if (blknbr == ROOT) { | 
| stcpy0 (data, &block[i], k);        /* get value */ | gbl_close (g); | 
| data[k] = EOL1;     /* append EOL */ | goto reopen; | 
|  | } | 
|  |  | 
|  | merr_raise (DBDGD); | 
 | goto quit; | goto quit; | 
|  |  | 
 | } | } | 
|  |  | 
| i += UNSIGN (block[i]); |  | 
| i++;            /* skip data */ |  | 
|  |  | 
| } |  | 
|  |  | 
| /* fast access failed. try normal path */ |  | 
| if (tryfast) { |  | 
| gbl_cache_miss (g); |  | 
| goto tfast0; |  | 
 | } | } | 
 |  |  | 
 | merr_raise (M7); |  | 
 | data[0] = EOL; |  | 
 |  |  | 
| goto quit;          /* variable not found */ | scanpblk (block, &addr, &found); | 
| } |  | 
| else { | addr += UNSIGN (block[addr]) + 2;   /* skip key */ | 
|  |  | 
| if (g->fast_path > 0) { | if ((blknbr = UNSIGN (block[addr]) * 65536 + UNSIGN (block[addr + 1]) * 256 + UNSIGN (block[addr + 2])) == g->last_block) { | 
| gbl_cache_miss (g); |  | 
| goto tfast0; |  | 
| } |  | 
|  |  | 
| if (typ == EMPTY) { |  | 
|  |  | 
| if (blknbr == ROOT) { |  | 
| //close (filedes); |  | 
| gbl_close (g); |  | 
| goto reopen; |  | 
| } |  | 
|  |  | 
 | merr_raise (DBDGD); | merr_raise (DBDGD); | 
 | goto quit; | goto quit; | 
 |  |  | 
 | } | } | 
 |  |  | 
| } | addr += PLEN;               /* skip data */ | 
|  | g->last_block = blknbr; | 
| scanpblk (block, &addr, &found); | g->fast_path = 1; | 
|  |  | 
| addr += UNSIGN (block[addr]) + 2;       /* skip key */ |  | 
 |  |  | 
| if ((blknbr = UNSIGN (block[addr]) * 65536 + UNSIGN (block[addr + 1]) * 256 + UNSIGN (block[addr + 2])) == g->last_block) { | if (merr () == INRPT) goto quit; | 
| merr_raise (DBDGD); |  | 
| goto quit; |  | 
| } |  | 
|  |  | 
| addr += PLEN;           /* skip data */ |  | 
| g->last_block = blknbr; |  | 
| g->fast_path = 1; |  | 
|  |  | 
| if (merr () == INRPT) goto quit; |  | 
 |  |  | 
 | } | } | 
 | }                                   /* end of get_sym */ | }                                   /* end of get_sym */ | 
| Line 1186  tfast2: | Line 1245  tfast2: | 
 | /* a KILL on an unsubscripted global deletes the entire file */ | /* a KILL on an unsubscripted global deletes the entire file */ | 
 | if (action == kill_sym && compactkey[0] == g_EOL) { | if (action == kill_sym && compactkey[0] == g_EOL) { | 
 |  |  | 
| lseek (g->fd, hdr_offset + ROOT, SEEK_SET); | /* note : UNIX does not tell other jobs that a file has been unlinked */ | 
|  |  | 
| /* note : UNIX does not tell other    */ |  | 
| block[BTYP] = EMPTY;            /* jobs that a file has been unlinked */ |  | 
|  |  | 
 | /* as long as they keep it open.      */ | /* as long as they keep it open.      */ | 
 | /* so we mark this global as EMPTY    */ | /* so we mark this global as EMPTY    */ | 
| write (g->fd, block, BLOCKLEN); | block[BTYP] = EMPTY; | 
|  |  | 
|  | gbl_write_block (g, ROOT, block); | 
 |  |  | 
 | gbl_unlock (g); | gbl_unlock (g); | 
 | gbl_close (g); | gbl_close (g); | 
| Line 1218  k_again:    /* entry point for repeated | Line 1275  k_again:    /* entry point for repeated | 
 |  |  | 
 | traceblk[trx] = blknbr; | traceblk[trx] = blknbr; | 
 | traceadr[trx] = 0; | traceadr[trx] = 0; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
|  |  | 
 | typ = block[BTYP]; | typ = block[BTYP]; | 
 |  |  | 
 | if (typ == DATA) { | if (typ == DATA) { | 
| Line 1264  k_again:    /* entry point for repeated | Line 1319  k_again:    /* entry point for repeated | 
 |  |  | 
 | datal = stlen (data); | datal = stlen (data); | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 |  |  | 
 | if (found != 2) {           /* new entry */ | if (found != 2) {           /* new entry */ | 
 |  |  | 
| Line 1290  k_again:    /* entry point for repeated | Line 1345  k_again:    /* entry point for repeated | 
 | } | } | 
 |  |  | 
 |  |  | 
| s10:            { | s10: | 
|  | { | 
 | long    len;                /*  insert key */ | long    len;                /*  insert key */ | 
 | char    key0[256]; | char    key0[256]; | 
 |  |  | 
| Line 1388  s10:            { | Line 1444  s10:            { | 
 |  |  | 
 | } | } | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, blknbr, block); | 
| write (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | if (traceadr[trx] == 0) update (g, compactkey, keyl); | if (traceadr[trx] == 0) update (g, compactkey, keyl); | 
 |  |  | 
| Line 1442  s10:            { | Line 1497  s10:            { | 
 | goto splitd; | goto splitd; | 
 | } | } | 
 |  |  | 
| s20: | s20: | 
 |  |  | 
 | i = offset; | i = offset; | 
 | k = addr + olddatal; | k = addr + olddatal; | 
| Line 1475  s20: | Line 1530  s20: | 
 | } | } | 
 |  |  | 
 | stcpy0 (&block[++addr], data, (long) datal); | stcpy0 (&block[++addr], data, (long) datal); | 
 | lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); |  | 
 | write (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
| gbl_update_tid (g); | gbl_write_block (g, blknbr, block); | 
 |  |  | 
 | break; | break; | 
 |  |  | 
| Line 1504  s20: | Line 1557  s20: | 
 |  |  | 
 | /* get following entry, eventually in the next blk */ | /* get following entry, eventually in the next blk */ | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 |  |  | 
 | if (addr >= offset) { | if (addr >= offset) { | 
 |  |  | 
 | if ((blknbr = UNSIGN (block[RLPTR]) * 65536 + UNSIGN (block[RLPTR + 1]) * 256 + UNSIGN (block[RLPTR + 2]))) { | if ((blknbr = UNSIGN (block[RLPTR]) * 65536 + UNSIGN (block[RLPTR + 1]) * 256 + UNSIGN (block[RLPTR + 2]))) { | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 | j1 = UNSIGN (block[0]); | j1 = UNSIGN (block[0]); | 
 |  |  | 
 | i = 0; | i = 0; | 
| Line 1592  s20: | Line 1644  s20: | 
 |  |  | 
 | goto quit; | goto quit; | 
 | }       /* no next block */ | }       /* no next block */ | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 | scandblk (block, &addr, &found); | scandblk (block, &addr, &found); | 
 |  |  | 
 | } | } | 
| Line 1641  s20: | Line 1692  s20: | 
 |  |  | 
 | while (i < keyl) if (compactkey[i++] & 01) | while (i < keyl) if (compactkey[i++] & 01) | 
 |  |  | 
| j1++; | j1++; | 
 | i = 0; | i = 0; | 
 | j = 0; | j = 0; | 
 | k = 0; | k = 0; | 
| Line 1674  s20: | Line 1725  s20: | 
 | while ((ch = UNSIGN (scratch[i++])) != g_EOL) { | while ((ch = UNSIGN (scratch[i++])) != g_EOL) { | 
 |  |  | 
 | ch0 = (ch >= SP ? (ch >> 1) :       /* 'string' chars */ | ch0 = (ch >= SP ? (ch >> 1) :       /* 'string' chars */ | 
| (ch < 20 ? (ch >> 1) + '0' :        /* 0...9          */ | (ch < 20 ? (ch >> 1) + '0' : /* 0...9          */ | 
| (ch >> 1) + SP));   /* '.' or '-'     */ | (ch >> 1) + SP));   /* '.' or '-'     */ | 
 |  |  | 
 |  |  | 
 | if (ch0 == DEL) { | if (ch0 == DEL) { | 
| Line 1750  s20: | Line 1801  s20: | 
 | goto quit;              /* no next block */ | goto quit;              /* no next block */ | 
 | } | } | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | addr = 0; | addr = 0; | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 | } | } | 
 |  |  | 
 | } | } | 
| Line 1774  s20: | Line 1824  s20: | 
 | goto quit;          /* no next block */ | goto quit;          /* no next block */ | 
 | } | } | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | addr = 0; | addr = 0; | 
 | } | } | 
| Line 1823  s20: | Line 1872  s20: | 
 | while ((ch = UNSIGN (key0[i++])) != g_EOL) { | while ((ch = UNSIGN (key0[i++])) != g_EOL) { | 
 |  |  | 
 | ch0 = (ch >= SP ? (ch >> 1) :   /* 'string' chars */ | ch0 = (ch >= SP ? (ch >> 1) :   /* 'string' chars */ | 
| (ch < 20 ? (ch >> 1) + '0' :            /* 0...9          */ | (ch < 20 ? (ch >> 1) + '0' :             /* 0...9          */ | 
| (ch >> 1) + SP));       /* '.' or '-'     */ | (ch >> 1) + SP));       /* '.' or '-'     */ | 
 |  |  | 
 |  |  | 
 | if (ch0 == DEL) { | if (ch0 == DEL) { | 
| Line 1900  s20: | Line 1949  s20: | 
 | } | } | 
 |  |  | 
 | ch0 = (ch >= SP ? (ch >> 1) :   /* 'string' chars */ | ch0 = (ch >= SP ? (ch >> 1) :   /* 'string' chars */ | 
| (ch < 20 ? (ch >> 1) + '0' :            /* 0...9          */ | (ch < 20 ? (ch >> 1) + '0' :             /* 0...9          */ | 
| (ch >> 1) + SP));       /* '.' or '-'     */ | (ch >> 1) + SP));       /* '.' or '-'     */ | 
 |  |  | 
 | if (ch0 == DEL) { | if (ch0 == DEL) { | 
 |  |  | 
| Line 1945  s20: | Line 1994  s20: | 
 |  |  | 
 | case kill_sym:                  /* search and destroy */ | case kill_sym:                  /* search and destroy */ | 
 |  |  | 
| killo:                          /* entry from killone section */ | killo:                          /* entry from killone section */ | 
 | offset = UNSIGN (block[OFFS]) * 256 + UNSIGN (block[OFFS + 1]); | offset = UNSIGN (block[OFFS]) * 256 + UNSIGN (block[OFFS + 1]); | 
 |  |  | 
 | i = 0; | i = 0; | 
| Line 1984  killo:    /* entry from killone section | Line 2033  killo:    /* entry from killone section | 
 |  |  | 
 | other = traceblk[--trx]; | other = traceblk[--trx]; | 
 | addr = traceadr[trx]; | addr = traceadr[trx]; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, other, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | addr += UNSIGN (block[addr]); | addr += UNSIGN (block[addr]); | 
 | addr += (2 + PLEN);     /* skip previous entry */ | addr += (2 + PLEN);     /* skip previous entry */ | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 | traceadr[trx] = addr; | traceadr[trx] = addr; | 
 |  |  | 
 | if (addr < offset) break; | if (addr < offset) break; | 
 |  |  | 
 | traceadr[trx] = 0; | traceadr[trx] = 0; | 
 | traceblk[trx] = UNSIGN (block[RLPTR]) * 65536 + | traceblk[trx] = UNSIGN (block[RLPTR]) * 65536 + | 
| UNSIGN (block[RLPTR + 1]) * 256 + | UNSIGN (block[RLPTR + 1]) * 256 + | 
| UNSIGN (block[RLPTR + 2]); | UNSIGN (block[RLPTR + 2]); | 
 |  |  | 
 | } | } | 
 |  |  | 
 | trx = trxsav; | trx = trxsav; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 | addr = 0; | addr = 0; | 
 | k = UNSIGN (block[0]); | k = UNSIGN (block[0]); | 
 | stcpy0 (key0, &block[2], k); | stcpy0 (key0, &block[2], k); | 
| Line 2098  killo:    /* entry from killone section | Line 2145  killo:    /* entry from killone section | 
 | if ((begadr == 0) && (endadr == offset)) {      /* block becomes empty */ | if ((begadr == 0) && (endadr == offset)) {      /* block becomes empty */ | 
 |  |  | 
 | long    left, | long    left, | 
| right; | right; | 
 | char    block0[BLOCKLEN]; | char    block0[BLOCKLEN]; | 
 |  |  | 
| p_empty:                /* entry if pointer block goes empty */ | p_empty:                /* entry if pointer block goes empty */ | 
 |  |  | 
 | left = UNSIGN (block[LLPTR]) * 65536 + | left = UNSIGN (block[LLPTR]) * 65536 + | 
| UNSIGN (block[LLPTR + 1]) * 256 + | UNSIGN (block[LLPTR + 1]) * 256 + | 
| UNSIGN (block[LLPTR + 2]); | UNSIGN (block[LLPTR + 2]); | 
 | right = UNSIGN (block[RLPTR]) * 65536 + | right = UNSIGN (block[RLPTR]) * 65536 + | 
| UNSIGN (block[RLPTR + 1]) * 256 + | UNSIGN (block[RLPTR + 1]) * 256 + | 
| UNSIGN (block[RLPTR + 2]); | UNSIGN (block[RLPTR + 2]); | 
 |  |  | 
 | if (left) { | if (left) { | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) left * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, left, block0); | 
| read (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | block0[RLPTR] = block[RLPTR]; | block0[RLPTR] = block[RLPTR]; | 
 | block0[RLPTR + 1] = block[RLPTR + 1]; | block0[RLPTR + 1] = block[RLPTR + 1]; | 
 | block0[RLPTR + 2] = block[RLPTR + 2]; | block0[RLPTR + 2] = block[RLPTR + 2]; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) left * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, left, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | } | } | 
 |  |  | 
 | if (right) { | if (right) { | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) right * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, right, block0); | 
| read (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | block0[LLPTR] = block[LLPTR]; | block0[LLPTR] = block[LLPTR]; | 
 | block0[LLPTR + 1] = block[LLPTR + 1]; | block0[LLPTR + 1] = block[LLPTR + 1]; | 
 | block0[LLPTR + 2] = block[LLPTR + 2]; | block0[LLPTR + 2] = block[LLPTR + 2]; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) right * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, right, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | } | } | 
 |  |  | 
| b_free (g->fd, blknbr);     /* modify free list */ | b_free (g, blknbr); /* modify free list */ | 
 |  |  | 
 | /* delete pointer */ | /* delete pointer */ | 
 | /**************************/ | /**************************/ | 
| Line 2151  p_empty:  /* entry if pointer block goes | Line 2194  p_empty:  /* entry if pointer block goes | 
 | blknbr = traceblk[--trx]; | blknbr = traceblk[--trx]; | 
 | addr = traceadr[trx]; | addr = traceadr[trx]; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) (blknbr) * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 | freecnt = UNSIGN (block[addr]) + 2 + PLEN; | freecnt = UNSIGN (block[addr]) + 2 + PLEN; | 
 |  |  | 
 | /* delete key */ | /* delete key */ | 
| Line 2164  p_empty:  /* entry if pointer block goes | Line 2206  p_empty:  /* entry if pointer block goes | 
 |  |  | 
 | if (blknbr == ROOT) {       /* global went empty */ | if (blknbr == ROOT) {       /* global went empty */ | 
 |  |  | 
| lseek (g->fd, hdr_offset + 0L, SEEK_SET); |  | 
 |  |  | 
 | /* note : UNIX does not tell other    */ | /* note : UNIX does not tell other    */ | 
 | block[BTYP] = EMPTY;    /* jobs that a file has been unlinked */ | block[BTYP] = EMPTY;    /* jobs that a file has been unlinked */ | 
 |  |  | 
 | /* as long as they keep it open.      */ | /* as long as they keep it open.      */ | 
 | /* so we mark this global as EMPTY    */ | /* so we mark this global as EMPTY    */ | 
| write (g->fd, block, BLOCKLEN); | gbl_write_block (g, 0L, block); | 
|  |  | 
 | gbl_close (g); | gbl_close (g); | 
 | unlink (filnam); | unlink (filnam); | 
 |  |  | 
| Line 2196  p_empty:  /* entry if pointer block goes | Line 2239  p_empty:  /* entry if pointer block goes | 
 |  |  | 
 | for (i = offset; i < offset + freecnt; block[i++] = 0); | for (i = offset; i < offset + freecnt; block[i++] = 0); | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) (blknbr) * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, blknbr, block); | 
| write (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | if (addr == 0) {        /* update of pointer */ | if (addr == 0) {        /* update of pointer */ | 
 | traceadr[trx] = 0; | traceadr[trx] = 0; | 
| Line 2227  p_empty:  /* entry if pointer block goes | Line 2269  p_empty:  /* entry if pointer block goes | 
 | j = block[begadr + 1]; | j = block[begadr + 1]; | 
 | k = 0; | k = 0; | 
 | if (begadr) | if (begadr) | 
| while (key0[k] == key1[k]) | while (key0[k] == key1[k]) | 
| k++;                /* new key_offset */ | k++;                /* new key_offset */ | 
 | if (k < j) { | if (k < j) { | 
| ch = j - k;         /* space requirement */ | ch = j - k;             /* space requirement */ | 
| block[begadr] = i + ch;     /* new key_length */ | block[begadr] = i + ch; /* new key_length */ | 
| block[begadr + 1] = k;      /* new key_offset */ | block[begadr + 1] = k;  /* new key_offset */ | 
| i = offset; | i = offset; | 
| j = i + ch; | j = i + ch; | 
| offset = j; | offset = j; | 
| begadr++; | begadr++; | 
| while (i > begadr) | while (i > begadr) | 
| block[j--] = block[i--]; | block[j--] = block[i--]; | 
| stcpy0 (&block[begadr + 1], &key0[k], ch); | stcpy0 (&block[begadr + 1], &key0[k], ch); | 
 | } | } | 
 | } | } | 
 | block[OFFS] = offset / 256; | block[OFFS] = offset / 256; | 
 | block[OFFS + 1] = offset % 256; | block[OFFS + 1] = offset % 256; | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); |  | 
| write (g->fd, block, BLOCKLEN); | gbl_write_block (g, blknbr, block); | 
|  |  | 
 | if (addr < 3) {         /* update of pointer */ | if (addr < 3) {         /* update of pointer */ | 
| traceadr[trx] = 0; | traceadr[trx] = 0; | 
| update (g, &block[2], (long) UNSIGN (block[0])); | update (g, &block[2], (long) UNSIGN (block[0])); | 
 | } | } | 
 | } | } | 
 |  |  | 
| Line 2256  p_empty:  /* entry if pointer block goes | Line 2299  p_empty:  /* entry if pointer block goes | 
 |  |  | 
 | break; | break; | 
 |  |  | 
| zinv: | zinv: | 
 |  |  | 
 | { | { | 
 | long    len; | long    len; | 
| Line 2270  zinv: | Line 2313  zinv: | 
 | data[0] = EOL1; | data[0] = EOL1; | 
 | goto quit; | goto quit; | 
 | }                   /* no previous block */ | }                   /* no previous block */ | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | addr = UNSIGN (block[OFFS]) * 256 + | addr = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 |  |  | 
 | } | } | 
 |  |  | 
| Line 2350  zinv: | Line 2392  zinv: | 
 | while ((ch = UNSIGN (scratch[i++])) != g_EOL) { | while ((ch = UNSIGN (scratch[i++])) != g_EOL) { | 
 |  |  | 
 | ch0 = (ch >= SP ? (ch >> 1) :       /* 'string' chars */ | ch0 = (ch >= SP ? (ch >> 1) :       /* 'string' chars */ | 
| (ch < 20 ? (ch >> 1) + '0' :        /* 0...9          */ | (ch < 20 ? (ch >> 1) + '0' : /* 0...9          */ | 
| (ch >> 1) + SP));   /* '.' or '-'     */ | (ch >> 1) + SP));   /* '.' or '-'     */ | 
 |  |  | 
 | if (ch0 == DEL) { | if (ch0 == DEL) { | 
 |  |  | 
| Line 2396  zinv: | Line 2438  zinv: | 
 |  |  | 
 | case zdata:                     /* nonstandard data function */ | case zdata:                     /* nonstandard data function */ | 
 |  |  | 
| { | { | 
| long counties[128]; | long counties[128]; | 
| char key0[256]; | char key0[256]; | 
| int icnt, icnt0, len; | int icnt, icnt0, len; | 
 |  |  | 
| i = 0; | i = 0; | 
 |  |  | 
| while (i < 128) counties[i++] = 0L;     /* init count;  */ | while (i < 128) counties[i++] = 0L; /* init count;  */ | 
 |  |  | 
| if (found == 2) {               /* ... advance to next entry */ | if (found == 2) {           /* ... advance to next entry */ | 
| addr += UNSIGN (block[addr]); | addr += UNSIGN (block[addr]); | 
| addr += 2;          /* skip key */ | addr += 2;              /* skip key */ | 
| addr += UNSIGN (block[addr]); | addr += UNSIGN (block[addr]); | 
| addr++;                     /* skip data */ | addr++;                 /* skip data */ | 
 |  |  | 
| counties[0] = 1L; | counties[0] = 1L; | 
| } | } | 
 |  |  | 
| offset = UNSIGN (block[OFFS]) * 256 + UNSIGN (block[OFFS + 1]); | offset = UNSIGN (block[OFFS]) * 256 + UNSIGN (block[OFFS + 1]); | 
| icnt = 0; | icnt = 0; | 
| i = 0; | i = 0; | 
 |  |  | 
| while ((ch = compactkey[i++]) != g_EOL) { | while ((ch = compactkey[i++]) != g_EOL) { | 
|  |  | 
| if (ch & 01) { |  | 
| icnt++; |  | 
| } |  | 
 |  |  | 
 |  | if (ch & 01) { | 
 |  | icnt++; | 
 | } | } | 
 |  |  | 
| len = i - 1; | } | 
| i = 0; |  | 
 |  |  | 
| while (i < addr) {              /* compute offset complete key */ | len = i - 1; | 
|  | i = 0; | 
|  |  | 
|  | while (i < addr) {          /* compute offset complete key */ | 
 |  |  | 
| icnt0 = UNSIGN (block[i++]); | icnt0 = UNSIGN (block[i++]); | 
| icnt0 += (j = UNSIGN (block[i++])); | icnt0 += (j = UNSIGN (block[i++])); | 
 |  |  | 
| while (j < icnt0) key0[j++] = block[i++]; | while (j < icnt0) key0[j++] = block[i++]; | 
 |  |  | 
| key0[j] = g_EOL; | key0[j] = g_EOL; | 
| i += UNSIGN (block[i]); | i += UNSIGN (block[i]); | 
 |  |  | 
| i++;                        /* skip data */ | i++;                    /* skip data */ | 
 |  |  | 
| } | } | 
 |  |  | 
| for (;;) {                      /* is it still a descendant ??? */ | for (;;) {                  /* is it still a descendant ??? */ | 
 |  |  | 
| if (addr >= offset) {       /* look in next block */ | if (addr >= offset) {   /* look in next block */ | 
 |  |  | 
| if ((blknbr = UNSIGN (block[RLPTR]) * 65536 + UNSIGN (block[RLPTR + 1]) * 256 + UNSIGN (block[RLPTR + 2])) == 0) { | if ((blknbr = UNSIGN (block[RLPTR]) * 65536 + UNSIGN (block[RLPTR + 1]) * 256 + UNSIGN (block[RLPTR + 2])) == 0) { | 
| break;              /* no next block */ | break;          /* no next block */ | 
| } | } | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
| addr = 0; | addr = 0; | 
| offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
 | UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 |  |  | 
| } | } | 
 |  |  | 
| i = UNSIGN (block[addr++]); | i = UNSIGN (block[addr++]); | 
| i += (j = UNSIGN (block[addr++])); | i += (j = UNSIGN (block[addr++])); | 
 |  |  | 
| while (j < i) key0[j++] = block[addr++]; | while (j < i) key0[j++] = block[addr++]; | 
 |  |  | 
| addr += UNSIGN (block[addr]); | addr += UNSIGN (block[addr]); | 
| addr++;                     /* skip data */ | addr++;                 /* skip data */ | 
| icnt0 = 0; | icnt0 = 0; | 
| i = 0; | i = 0; | 
 |  |  | 
| while (i < j) if (key0[i++] & 01) | while (i < j) if (key0[i++] & 01) | 
 |  |  | 
| icnt0++; | icnt0++; | 
 |  |  | 
| if (icnt0 <= icnt) break; | if (icnt0 <= icnt) break; | 
 |  |  | 
| i = 0; | i = 0; | 
 |  |  | 
| while (i < len) { | while (i < len) { | 
 |  |  | 
| if (key0[i] != compactkey[i]) break; | if (key0[i] != compactkey[i]) break; | 
 |  |  | 
| i++; | i++; | 
 |  |  | 
| } | } | 
 |  |  | 
| if (i < len) break; | if (i < len) break; | 
 |  |  | 
| counties[icnt0 - icnt]++; | counties[icnt0 - icnt]++; | 
 |  |  | 
| } | } | 
 |  |  | 
| i = 128; | i = 128; | 
 |  |  | 
| while (counties[--i] == 0L); | while (counties[--i] == 0L); | 
 |  |  | 
| lintstr (data, counties[0]); | lintstr (data, counties[0]); | 
 |  |  | 
| j = 1; | j = 1; | 
| tmp1[0] = ','; | tmp1[0] = ','; | 
 |  |  | 
| while (j <= i) { | while (j <= i) { | 
| lintstr (&tmp1[1], counties[j++]); | lintstr (&tmp1[1], counties[j++]); | 
| stcat (data, tmp1); | stcat (data, tmp1); | 
| } |  | 
|  |  | 
 | } | } | 
 |  |  | 
 |  | } | 
 |  |  | 
| break; | break; | 
 |  |  | 
 | case getinc: | case getinc: | 
 |  |  | 
| { | { | 
| int     setopsav; | int     setopsav; | 
 |  |  | 
| setopsav = setop; | setopsav = setop; | 
| setop = '+'; | setop = '+'; | 
| data[0] = '1'; | data[0] = '1'; | 
| data[1] = EOL; | data[1] = EOL; | 
 |  |  | 
| global  (set_sym, key, data); | global  (set_sym, key, data); | 
 |  |  | 
| setop = setopsav; | setop = setopsav; | 
 |  |  | 
| return; | return; | 
| } | } | 
 |  |  | 
 | case killone: | case killone: | 
|  | { | 
| { | if (found == 2) goto killo;         /* entry found use normal kill routine */ | 
| if (found == 2) goto killo;             /* entry found use normal kill routine */ |  | 
 |  |  | 
| goto quit; | goto quit; | 
| } | } | 
|  |  | 
| case merge_sym: |  | 
|  |  | 
| printf("MERGE NOT IMPLEMENTED FOR GLOBALS\n"); |  | 
|  |  | 
| #ifdef DEBUG_GBL |  | 
|  |  | 
| int loop; |  | 
|  |  | 
| printf ("DEBUG MERGE: "); |  | 
| printf ("[key] is ["); |  | 
|  |  | 
| for (loop = 0; key[loop] != EOL; loop++) printf ("%c", (key[loop] == DELIM) ? '!' : key[loop]); |  | 
|  |  | 
| printf ("]\r\n"); |  | 
| printf ("[data] is ["); |  | 
|  |  | 
| for(loop = 0; data[loop] != EOL; loop++) printf ("%c", (data[loop] == DELIM) ? '!' : data[loop]); |  | 
|  |  | 
| printf("]\r\n"); |  | 
|  |  | 
| #endif |  | 
| return; |  | 
 |  |  | 
 | default: | default: | 
 |  |  | 
| Line 2580  splitd:    /* split data block in two se | Line 2597  splitd:    /* split data block in two se | 
 | /* 'addr' there I would like to insert, if possible (which is not) */ | /* 'addr' there I would like to insert, if possible (which is not) */ | 
 | /* 'offset' filled up to this limit */ | /* 'offset' filled up to this limit */ | 
 |  |  | 
| getnewblk (g->fd, &newblk); /* get a new block */ | getnewblk (g, &newblk);     /* get a new block */ | 
 |  |  | 
 | /* if we have to insert at the begin or end of a block  */ | /* if we have to insert at the begin or end of a block  */ | 
 | /* we don't split - we just start a new block           */ | /* we don't split - we just start a new block           */ | 
| Line 2588  splitd:    /* split data block in two se | Line 2605  splitd:    /* split data block in two se | 
 |  |  | 
 | if (addr >= offset) { | if (addr >= offset) { | 
 | long    right, | long    right, | 
| right1, | right1, | 
| right2; | right2; | 
 |  |  | 
 | right = UNSIGN (block[RLPTR]); | right = UNSIGN (block[RLPTR]); | 
 | right1 = UNSIGN (block[RLPTR + 1]); | right1 = UNSIGN (block[RLPTR + 1]); | 
| Line 2598  splitd:    /* split data block in two se | Line 2615  splitd:    /* split data block in two se | 
 | block[RLPTR + 1] = newblk % 65536 / 256; | block[RLPTR + 1] = newblk % 65536 / 256; | 
 | block[RLPTR + 2] = newblk % 256; | block[RLPTR + 2] = newblk % 256; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, blknbr, block); | 
| write (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | block[RLPTR] = right; | block[RLPTR] = right; | 
 | block[RLPTR + 1] = right1; | block[RLPTR + 1] = right1; | 
| Line 2618  splitd:    /* split data block in two se | Line 2634  splitd:    /* split data block in two se | 
 |  |  | 
 | char    block0[BLOCKLEN]; | char    block0[BLOCKLEN]; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, other, block0); | 
| read (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | block0[LLPTR] = blknbr / 65536; | block0[LLPTR] = blknbr / 65536; | 
 | block0[LLPTR + 1] = blknbr % 65536 / 256; | block0[LLPTR + 1] = blknbr % 65536 / 256; | 
 | block0[LLPTR + 2] = blknbr % 256; | block0[LLPTR + 2] = blknbr % 256; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, other, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
|  |  | 
 | } | } | 
 |  |  | 
 | goto spltex; | goto spltex; | 
| Line 2644  splitd:    /* split data block in two se | Line 2658  splitd:    /* split data block in two se | 
 | block[LLPTR + 1] = newblk % 65536 / 256; | block[LLPTR + 1] = newblk % 65536 / 256; | 
 | block[LLPTR + 2] = newblk % 256; | block[LLPTR + 2] = newblk % 256; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, blknbr, block); | 
| write (g->fd, block, BLOCKLEN); |  | 
|  |  | 
 | block[LLPTR] = left; | block[LLPTR] = left; | 
 | block[LLPTR + 1] = left1; | block[LLPTR + 1] = left1; | 
 | block[LLPTR + 2] = left2; | block[LLPTR + 2] = left2; | 
| Line 2666  splitd:    /* split data block in two se | Line 2679  splitd:    /* split data block in two se | 
 | } | } | 
 |  |  | 
 | /* other is ***always*** zero !!! | /* other is ***always*** zero !!! | 
| * if (other=left*65536+left1*256+left2) up-date RL-PTR of LL-block | * if (other=left*65536+left1*256+left2) up-date RL-PTR of LL-block | 
| * { char block0[BLOCKLEN]; | * { char block0[BLOCKLEN]; | 
| * lseek(filedes,(long)other*(long)(BLOCKLEN),0); | * lseek(filedes,(long)other*(long)(BLOCKLEN),0); | 
| * read(filedes,block0,BLOCKLEN); | * read(filedes,block0,BLOCKLEN); | 
| * block0[RLPTR  ]=blknbr/65536; | * block0[RLPTR  ]=blknbr/65536; | 
| * block0[RLPTR+1]=blknbr%65536/256; | * block0[RLPTR+1]=blknbr%65536/256; | 
| * block0[RLPTR+2]=blknbr%256; | * block0[RLPTR+2]=blknbr%256; | 
| * lseek(filedes,(long)other*(long)(BLOCKLEN),0); | * lseek(filedes,(long)other*(long)(BLOCKLEN),0); | 
| * write(filedes,block0,BLOCKLEN); | * write(filedes,block0,BLOCKLEN); | 
| * } | * } | 
| */ | */ | 
 |  |  | 
 | goto spltex; | goto spltex; | 
 |  |  | 
| Line 2758  splitd:    /* split data block in two se | Line 2771  splitd:    /* split data block in two se | 
 |  |  | 
 | /* update rightlink and leftlink pointers */ | /* update rightlink and leftlink pointers */ | 
 | other = UNSIGN (block[RLPTR]) * 65536 + | other = UNSIGN (block[RLPTR]) * 65536 + | 
| UNSIGN (block[RLPTR + 1]) * 256 + | UNSIGN (block[RLPTR + 1]) * 256 + | 
| UNSIGN (block[RLPTR + 2]); | UNSIGN (block[RLPTR + 2]); | 
 | block0[RLPTR] = block[RLPTR]; | block0[RLPTR] = block[RLPTR]; | 
 | block0[RLPTR + 1] = block[RLPTR + 1]; | block0[RLPTR + 1] = block[RLPTR + 1]; | 
 | block0[RLPTR + 2] = block[RLPTR + 2]; | block0[RLPTR + 2] = block[RLPTR + 2]; | 
| Line 2770  splitd:    /* split data block in two se | Line 2783  splitd:    /* split data block in two se | 
 | block0[LLPTR + 1] = blknbr % 65536 / 256; | block0[LLPTR + 1] = blknbr % 65536 / 256; | 
 | block0[LLPTR + 2] = blknbr % 256; | block0[LLPTR + 2] = blknbr % 256; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) (newblk) * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, newblk, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | offset = limit; | offset = limit; | 
 | /* insert new block in pointer structure */ | /* insert new block in pointer structure */ | 
| Line 2781  splitd:    /* split data block in two se | Line 2793  splitd:    /* split data block in two se | 
 | /* up-date LL-PTR of RL-block */ | /* up-date LL-PTR of RL-block */ | 
 | if (other != 0) { | if (other != 0) { | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, other, block0); | 
| read (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | block0[LLPTR] = newblk / 65536; | block0[LLPTR] = newblk / 65536; | 
 | block0[LLPTR + 1] = newblk % 65536 / 256; | block0[LLPTR + 1] = newblk % 65536 / 256; | 
 | block0[LLPTR + 2] = newblk % 256; | block0[LLPTR + 2] = newblk % 256; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, other, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | } | } | 
 |  |  | 
| Line 2798  splitd:    /* split data block in two se | Line 2808  splitd:    /* split data block in two se | 
 | /* save old block away and make new block the current block */ | /* save old block away and make new block the current block */ | 
 | /* update rightlink and leftlink pointers */ | /* update rightlink and leftlink pointers */ | 
 | other = UNSIGN (block[RLPTR]) * 65536 + | other = UNSIGN (block[RLPTR]) * 65536 + | 
| UNSIGN (block[RLPTR + 1]) * 256 + | UNSIGN (block[RLPTR + 1]) * 256 + | 
| UNSIGN (block[RLPTR + 2]); | UNSIGN (block[RLPTR + 2]); | 
 | block0[RLPTR] = block[RLPTR]; | block0[RLPTR] = block[RLPTR]; | 
 | block0[RLPTR + 1] = block[RLPTR + 1]; | block0[RLPTR + 1] = block[RLPTR + 1]; | 
 | block0[RLPTR + 2] = block[RLPTR + 2]; | block0[RLPTR + 2] = block[RLPTR + 2]; | 
| Line 2810  splitd:    /* split data block in two se | Line 2820  splitd:    /* split data block in two se | 
 | block0[LLPTR + 1] = blknbr % 65536 / 256; | block0[LLPTR + 1] = blknbr % 65536 / 256; | 
 | block0[LLPTR + 2] = blknbr % 256; | block0[LLPTR + 2] = blknbr % 256; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, blknbr, block); | 
| write (g->fd, block, BLOCKLEN); |  | 
 | stcpy0 (block, block0, (long) BLOCKLEN); | stcpy0 (block, block0, (long) BLOCKLEN); | 
 |  |  | 
 | traceadr[trx] = (addr -= limit); | traceadr[trx] = (addr -= limit); | 
| Line 2823  splitd:    /* split data block in two se | Line 2833  splitd:    /* split data block in two se | 
 | /* up-date LL-PTR of RL-block */ | /* up-date LL-PTR of RL-block */ | 
 | if (other != 0) { | if (other != 0) { | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, other, block0); | 
| read (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | block0[LLPTR] = newblk / 65536; | block0[LLPTR] = newblk / 65536; | 
 | block0[LLPTR + 1] = newblk % 65536 / 256; | block0[LLPTR + 1] = newblk % 65536 / 256; | 
 | block0[LLPTR + 2] = newblk % 256; | block0[LLPTR + 2] = newblk % 256; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, other, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | } | } | 
 |  |  | 
| Line 2866  static void splitp (global_handle *g, ch | Line 2874  static void splitp (global_handle *g, ch | 
 | unsigned long newblk; | unsigned long newblk; | 
 | unsigned long other; | unsigned long other; | 
 | register int i, j; | register int i, j; | 
 |  |  | 
 | long hdr_offset; |  | 
 |  |  | 
 | hdr_offset = sizeof (global_header); |  | 
 |  |  | 
| getnewblk (g->fd, &newblk); /* get a new block */ | getnewblk (g, &newblk);     /* get a new block */ | 
 |  |  | 
 | if (*blknbr == ROOT) {              /* ROOT overflow is special */ | if (*blknbr == ROOT) {              /* ROOT overflow is special */ | 
 |  |  | 
| Line 2898  static void splitp (global_handle *g, ch | Line 2902  static void splitp (global_handle *g, ch | 
 |  |  | 
 | /* update number of blocks ! */ | /* update number of blocks ! */ | 
 | i = UNSIGN (block0[NRBLK]) * 65536 + | i = UNSIGN (block0[NRBLK]) * 65536 + | 
| UNSIGN (block0[NRBLK + 1]) * 256 + | UNSIGN (block0[NRBLK + 1]) * 256 + | 
| UNSIGN (block0[NRBLK + 2]) + 1; | UNSIGN (block0[NRBLK + 2]) + 1; | 
 |  |  | 
 | block0[NRBLK] = i / 65536; | block0[NRBLK] = i / 65536; | 
 | block0[NRBLK + 1] = i % 65536 / 256; | block0[NRBLK + 1] = i % 65536 / 256; | 
 | block0[NRBLK + 2] = i % 256; | block0[NRBLK + 2] = i % 256; | 
 | block0[BTYP] = POINTER; | block0[BTYP] = POINTER; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ROOT, SEEK_SET); | gbl_write_block (g, ROOT, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | /* shift trace_stack */ | /* shift trace_stack */ | 
 | j = trx++; | j = trx++; | 
| Line 2924  static void splitp (global_handle *g, ch | Line 2927  static void splitp (global_handle *g, ch | 
 | traceblk[1] = newblk; | traceblk[1] = newblk; | 
 | *blknbr = newblk; | *blknbr = newblk; | 
 |  |  | 
| getnewblk (g->fd, &newblk);     /* get a new block */ | getnewblk (g, &newblk); /* get a new block */ | 
 |  |  | 
 | } | } | 
 |  |  | 
| Line 2966  static void splitp (global_handle *g, ch | Line 2969  static void splitp (global_handle *g, ch | 
 |  |  | 
 | /* update rightlink and leftlink pointers */ | /* update rightlink and leftlink pointers */ | 
 | other = UNSIGN (block[RLPTR]) * 65536 + | other = UNSIGN (block[RLPTR]) * 65536 + | 
| UNSIGN (block[RLPTR + 1]) * 256 + | UNSIGN (block[RLPTR + 1]) * 256 + | 
| UNSIGN (block[RLPTR + 2]); | UNSIGN (block[RLPTR + 2]); | 
 | block0[RLPTR] = block[RLPTR]; | block0[RLPTR] = block[RLPTR]; | 
 | block0[RLPTR + 1] = block[RLPTR + 1]; | block0[RLPTR + 1] = block[RLPTR + 1]; | 
 | block0[RLPTR + 2] = block[RLPTR + 2]; | block0[RLPTR + 2] = block[RLPTR + 2]; | 
| Line 2978  static void splitp (global_handle *g, ch | Line 2981  static void splitp (global_handle *g, ch | 
 | block0[LLPTR + 1] = (*blknbr) % 65536 / 256; | block0[LLPTR + 1] = (*blknbr) % 65536 / 256; | 
 | block0[LLPTR + 2] = (*blknbr) % 256; | block0[LLPTR + 2] = (*blknbr) % 256; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) (newblk) * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, newblk, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | (*offs) = limit; | (*offs) = limit; | 
 |  |  | 
| Line 2988  static void splitp (global_handle *g, ch | Line 2990  static void splitp (global_handle *g, ch | 
 | /* up-date LL-PTR of RL-block */ | /* up-date LL-PTR of RL-block */ | 
 | if (other != 0) { | if (other != 0) { | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, other, block0); | 
| read (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | block0[LLPTR] = newblk / 65536; | block0[LLPTR] = newblk / 65536; | 
 | block0[LLPTR + 1] = newblk % 65536 / 256; | block0[LLPTR + 1] = newblk % 65536 / 256; | 
 | block0[LLPTR + 2] = newblk % 256; | block0[LLPTR + 2] = newblk % 256; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, other, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | } | } | 
 |  |  | 
| Line 3005  static void splitp (global_handle *g, ch | Line 3005  static void splitp (global_handle *g, ch | 
 |  |  | 
 | /* update rightlink and leftlink pointers */ | /* update rightlink and leftlink pointers */ | 
 | other = UNSIGN (block[RLPTR]) * 65536 + | other = UNSIGN (block[RLPTR]) * 65536 + | 
| UNSIGN (block[RLPTR + 1]) * 256 + | UNSIGN (block[RLPTR + 1]) * 256 + | 
| UNSIGN (block[RLPTR + 2]); | UNSIGN (block[RLPTR + 2]); | 
 |  |  | 
 | block0[RLPTR] = block[RLPTR]; | block0[RLPTR] = block[RLPTR]; | 
 | block0[RLPTR + 1] = block[RLPTR + 1]; | block0[RLPTR + 1] = block[RLPTR + 1]; | 
| Line 3020  static void splitp (global_handle *g, ch | Line 3020  static void splitp (global_handle *g, ch | 
 |  |  | 
 | (*addr) -= limit; | (*addr) -= limit; | 
 | (*offs) -= limit; | (*offs) -= limit; | 
 |  |  | 
 |  | gbl_write_block (g, *blknbr, block); | 
 |  |  | 
 | lseek (g->fd, hdr_offset + ((long) (*blknbr) * (long) (BLOCKLEN)), SEEK_SET); |  | 
 | write (g->fd, block, BLOCKLEN); |  | 
 | stcpy0 (block, block0, (long) BLOCKLEN); | stcpy0 (block, block0, (long) BLOCKLEN); | 
 |  |  | 
 | (*blknbr) = newblk; | (*blknbr) = newblk; | 
| Line 3032  static void splitp (global_handle *g, ch | Line 3032  static void splitp (global_handle *g, ch | 
 | /* up-date LL-PTR of RL-block */ | /* up-date LL-PTR of RL-block */ | 
 | if (other != 0) { | if (other != 0) { | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, other, block0); | 
| read (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | block0[LLPTR] = newblk / 65536; | block0[LLPTR] = newblk / 65536; | 
 | block0[LLPTR + 1] = newblk % 65536 / 256; | block0[LLPTR + 1] = newblk % 65536 / 256; | 
 | block0[LLPTR + 2] = newblk % 256; | block0[LLPTR + 2] = newblk % 256; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) other * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, other, block0); | 
| write (g->fd, block0, BLOCKLEN); |  | 
 |  |  | 
 | } | } | 
 |  |  | 
| Line 3062  static void update (global_handle *g, ch | Line 3060  static void update (global_handle *g, ch | 
 | unsigned long blknbr; | unsigned long blknbr; | 
 | char block[BLOCKLEN]; | char block[BLOCKLEN]; | 
 | long i, j, k; | long i, j, k; | 
 | long hdr_offset; |  | 
 |  |  | 
 | hdr_offset = sizeof (global_header); |  | 
 |  |  | 
 | while (traceadr[trx] == 0) {        /* update of pointer blocks necessary */ | while (traceadr[trx] == 0) {        /* update of pointer blocks necessary */ | 
 |  |  | 
| Line 3072  static void update (global_handle *g, ch | Line 3067  static void update (global_handle *g, ch | 
 |  |  | 
 | blknbr = traceblk[trx]; | blknbr = traceblk[trx]; | 
 | addr = traceadr[trx]; | addr = traceadr[trx]; | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | { | { | 
 | long    oldkeyl; | long    oldkeyl; | 
| Line 3085  static void update (global_handle *g, ch | Line 3079  static void update (global_handle *g, ch | 
 | j = oldkeyl - keyl; | j = oldkeyl - keyl; | 
 |  |  | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 |  |  | 
 | if (j > 0) {                /* surplus space */ | if (j > 0) {                /* surplus space */ | 
 |  |  | 
| Line 3124  static void update (global_handle *g, ch | Line 3118  static void update (global_handle *g, ch | 
 | while (i < keyl) block[j++] = ins_key[i++]; | while (i < keyl) block[j++] = ins_key[i++]; | 
 |  |  | 
 | /* block pointed to remains the same */ | /* block pointed to remains the same */ | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, blknbr, block); | 
| write (g->fd, block, BLOCKLEN); |  | 
|  |  | 
 | } | } | 
|  |  | 
| lseek (g->fd, hdr_offset + ((long) blknbr * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blknbr, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | } | } | 
 |  |  | 
| Line 3154  static void insert (global_handle *g, ch | Line 3145  static void insert (global_handle *g, ch | 
 | long needed; | long needed; | 
 | long addr; | long addr; | 
 | register int i, k; | register int i, k; | 
 | long hdr_offset; |  | 
 |  |  | 
 | hdr_offset = sizeof (global_header); |  | 
 |  |  | 
 | trxsav = trx--; | trxsav = trx--; | 
 | blk = traceblk[trx]; | blk = traceblk[trx]; | 
 | addr = traceadr[trx]; | addr = traceadr[trx]; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) (blk) * (long) (BLOCKLEN)), SEEK_SET); | gbl_read_block (g, blk, block); | 
| read (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 |  |  | 
 | if (traceadr[trx + 1] != (-1)) { | if (traceadr[trx + 1] != (-1)) { | 
 | addr += UNSIGN (block[addr]); | addr += UNSIGN (block[addr]); | 
| Line 3199  static void insert (global_handle *g, ch | Line 3186  static void insert (global_handle *g, ch | 
 | block[i++] = blknbr % 65536 / 256; | block[i++] = blknbr % 65536 / 256; | 
 | block[i] = blknbr % 256; | block[i] = blknbr % 256; | 
 |  |  | 
| lseek (g->fd, hdr_offset + ((long) (blk) * (long) (BLOCKLEN)), SEEK_SET); | gbl_write_block (g, blk, block); | 
| write (g->fd, block, BLOCKLEN); |  | 
 |  |  | 
 | trx = trxsav; | trx = trxsav; | 
 |  |  | 
| Line 3212  static void insert (global_handle *g, ch | Line 3198  static void insert (global_handle *g, ch | 
 | *  filedes:    global file descriptor | *  filedes:    global file descriptor | 
 | *  blknbr:     block to be freed | *  blknbr:     block to be freed | 
 | */ | */ | 
| static void b_free (short filedes, unsigned long blknbr) | static void b_free (global_handle *g, unsigned long blknbr) | 
 | { | { | 
 | char block0[BLOCKLEN]; | char block0[BLOCKLEN]; | 
 | unsigned long free; | unsigned long free; | 
 | unsigned long other; | unsigned long other; | 
 | long i; | long i; | 
 | long offset; | long offset; | 
 | long hdr_offset; |  | 
 |  |  | 
 | hdr_offset = sizeof (global_header); |  | 
 |  |  | 
 | /* mark block as empty */ | /* mark block as empty */ | 
| lseek (filedes, hdr_offset + ((long) (blknbr) * BLOCKLEN), SEEK_SET); | gbl_read_block (g, blknbr, block0); | 
| read (filedes, block0, BLOCKLEN); |  | 
|  |  | 
| block0[BTYP] = EMPTY; |  | 
 |  |  | 
| lseek (filedes, hdr_offset + ((long) (blknbr) * BLOCKLEN), SEEK_SET); | block0[BTYP] = EMPTY; | 
| write (filedes, block0, BLOCKLEN); |  | 
|  | gbl_write_block (g, blknbr, block0); | 
 |  |  | 
 | /* do we have a list of free blocks? */ | /* do we have a list of free blocks? */ | 
| lseek (filedes, hdr_offset + ROOT, SEEK_SET); | gbl_read_block (g, ROOT, block0); | 
| read (filedes, block0, BLOCKLEN); |  | 
 |  |  | 
 | if ((free = UNSIGN (block0[FREE]) * 65536 + UNSIGN (block0[FREE + 1]) * 256 + UNSIGN (block0[FREE + 2]))) { | if ((free = UNSIGN (block0[FREE]) * 65536 + UNSIGN (block0[FREE + 1]) * 256 + UNSIGN (block0[FREE + 2]))) { | 
 |  |  | 
 | for (;;) { | for (;;) { | 
|  |  | 
| lseek (filedes, hdr_offset + ((long) free * (long) BLOCKLEN), SEEK_SET); | gbl_read_block (g, free, block0); | 
| read (filedes, block0, BLOCKLEN); |  | 
 |  |  | 
 | other = UNSIGN (block0[RLPTR]) * 65536 + | other = UNSIGN (block0[RLPTR]) * 65536 + | 
| UNSIGN (block0[RLPTR + 1]) * 256 + | UNSIGN (block0[RLPTR + 1]) * 256 + | 
| UNSIGN (block0[RLPTR + 2]); | UNSIGN (block0[RLPTR + 2]); | 
 |  |  | 
 | if (other == 0) break; | if (other == 0) break; | 
 |  |  | 
| Line 3261  static void b_free (short filedes, unsig | Line 3240  static void b_free (short filedes, unsig | 
 | offset -= PLEN; | offset -= PLEN; | 
 | other = UNSIGN (block0[offset]) * 65536 + | other = UNSIGN (block0[offset]) * 65536 + | 
 |  |  | 
| UNSIGN (block0[offset + 1]) * 256 + | UNSIGN (block0[offset + 1]) * 256 + | 
| UNSIGN (block0[offset + 2]); | UNSIGN (block0[offset + 2]); | 
 |  |  | 
 | block0[offset] = 0; | block0[offset] = 0; | 
 | block0[offset + 1] = 0; | block0[offset + 1] = 0; | 
| Line 3272  static void b_free (short filedes, unsig | Line 3251  static void b_free (short filedes, unsig | 
 | block0[RLPTR] = other / 65536; | block0[RLPTR] = other / 65536; | 
 | block0[RLPTR + 1] = other % 65536 / 256; | block0[RLPTR + 1] = other % 65536 / 256; | 
 | block0[RLPTR + 2] = other % 256; | block0[RLPTR + 2] = other % 256; | 
|  |  | 
| lseek (filedes, hdr_offset + ((long) free * (long) BLOCKLEN), SEEK_SET); | gbl_write_block (g, free, block0); | 
| write (filedes, block0, BLOCKLEN); |  | 
 |  |  | 
 | for (i = 0; i < BLOCKLEN; block0[i++] = 0); /* clear block */ | for (i = 0; i < BLOCKLEN; block0[i++] = 0); /* clear block */ | 
 |  |  | 
| Line 3290  static void b_free (short filedes, unsig | Line 3268  static void b_free (short filedes, unsig | 
 |  |  | 
 | } | } | 
 | else { | else { | 
|  | getnewblk (g, &free); | 
| getnewblk (filedes, &free); |  | 
 |  |  | 
 | /* set FBLK free blocks pointer */ | /* set FBLK free blocks pointer */ | 
| lseek (filedes, hdr_offset + ROOT, SEEK_SET); | gbl_read_block (g, ROOT, block0); | 
| read (filedes, block0, BLOCKLEN); |  | 
 |  |  | 
 | block0[FREE] = free / 65536; | block0[FREE] = free / 65536; | 
 | block0[FREE + 1] = free % 65536 / 256; | block0[FREE + 1] = free % 65536 / 256; | 
 | block0[FREE + 2] = free % 256; | block0[FREE + 2] = free % 256; | 
|  |  | 
| lseek (filedes, hdr_offset + ROOT, SEEK_SET); | gbl_write_block (g, ROOT, block0); | 
| write (filedes, block0, BLOCKLEN); |  | 
 |  |  | 
 | for (i = 0; i < BLOCKLEN; block0[i++] = 0);     /* clear block */ | for (i = 0; i < BLOCKLEN; block0[i++] = 0);     /* clear block */ | 
 |  |  | 
| Line 3317  static void b_free (short filedes, unsig | Line 3292  static void b_free (short filedes, unsig | 
 | block0[OFFS] = offset / 256; | block0[OFFS] = offset / 256; | 
 | block0[OFFS + 1] = offset % 256; | block0[OFFS + 1] = offset % 256; | 
 |  |  | 
| lseek (filedes, hdr_offset + ((long) free * (long) BLOCKLEN), SEEK_SET); | gbl_write_block (g, free, block0); | 
| write (filedes, block0, BLOCKLEN); |  | 
 |  |  | 
 | return; | return; | 
 | }                                       /* end of b_free() */ | }                                       /* end of b_free() */ | 
| Line 3391  static void scandblk (char *block, long | Line 3365  static void scandblk (char *block, long | 
 | char key0[256]; | char key0[256]; | 
 |  |  | 
 | offset = UNSIGN (block[OFFS]) * 256 + | offset = UNSIGN (block[OFFS]) * 256 + | 
| UNSIGN (block[OFFS + 1]); | UNSIGN (block[OFFS + 1]); | 
 |  |  | 
 | while (i < offset) { | while (i < offset) { | 
 |  |  | 
| Line 3438  static void scandblk (char *block, long | Line 3412  static void scandblk (char *block, long | 
 | *  filedes:    global file descriptor | *  filedes:    global file descriptor | 
 | *  blknbr:     number of new block | *  blknbr:     number of new block | 
 | */ | */ | 
| static void getnewblk (int filedes, unsigned long *blknbr) | static void getnewblk (global_handle *g, unsigned long *blknbr) | 
 | { | { | 
 | char nblock[BLOCKLEN]; | char nblock[BLOCKLEN]; | 
 | unsigned long freeblks, no_of_blks; | unsigned long freeblks, no_of_blks; | 
 | long other; | long other; | 
 | long offset; | long offset; | 
 | long hdr_offset; |  | 
 |  |  | 
| hdr_offset = sizeof (global_header); | gbl_read_block (g, ROOT, nblock); | 
|  |  | 
| lseek (filedes, hdr_offset + ROOT, SEEK_SET); |  | 
| read (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | freeblks = UNSIGN (nblock[FREE]) * 65536 + UNSIGN (nblock[FREE + 1]) * 256 + UNSIGN (nblock[FREE + 2]); | freeblks = UNSIGN (nblock[FREE]) * 65536 + UNSIGN (nblock[FREE + 1]) * 256 + UNSIGN (nblock[FREE + 2]); | 
 | no_of_blks = UNSIGN (nblock[NRBLK]) * 65536 + UNSIGN (nblock[NRBLK + 1]) * 256 + UNSIGN (nblock[NRBLK + 2]); | no_of_blks = UNSIGN (nblock[NRBLK]) * 65536 + UNSIGN (nblock[NRBLK + 1]) * 256 + UNSIGN (nblock[NRBLK + 2]); | 
 |  |  | 
 | if (freeblks) { | if (freeblks) { | 
|  |  | 
| lseek (filedes, hdr_offset + ((long) (freeblks) * BLOCKLEN), SEEK_SET); | gbl_read_block (g, freeblks, nblock); | 
| read (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | offset = UNSIGN (nblock[OFFS]) * 256 + UNSIGN (nblock[OFFS + 1]); | offset = UNSIGN (nblock[OFFS]) * 256 + UNSIGN (nblock[OFFS + 1]); | 
 |  |  | 
| Line 3469  static void getnewblk (int filedes, unsi | Line 3438  static void getnewblk (int filedes, unsi | 
 | /* update RL-block, if any */ | /* update RL-block, if any */ | 
 | if (other) { | if (other) { | 
 |  |  | 
| lseek (filedes, hdr_offset + ((long) (other) * BLOCKLEN), SEEK_SET); | gbl_read_block (g, other, nblock); | 
| read (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | nblock[LLPTR] = 0; | nblock[LLPTR] = 0; | 
 | nblock[LLPTR + 1] = 0; | nblock[LLPTR + 1] = 0; | 
 | nblock[LLPTR + 2] = 0; | nblock[LLPTR + 2] = 0; | 
|  |  | 
| lseek (filedes, hdr_offset + ((long) (other) * BLOCKLEN), SEEK_SET); | gbl_write_block (g, other, nblock); | 
| write (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | } | } | 
 |  |  | 
 | /* update ROOT block */ | /* update ROOT block */ | 
| lseek (filedes, hdr_offset + ROOT, SEEK_SET); | gbl_read_block (g, ROOT, nblock); | 
| read (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | nblock[FREE] = other / 65536; | nblock[FREE] = other / 65536; | 
 | nblock[FREE + 1] = other % 65536 / 256; | nblock[FREE + 1] = other % 65536 / 256; | 
 | nblock[FREE + 2] = other % 256; | nblock[FREE + 2] = other % 256; | 
|  |  | 
| lseek (filedes, hdr_offset + ROOT, SEEK_SET); | gbl_write_block (g, ROOT, nblock); | 
| write (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | return; | return; | 
 |  |  | 
| Line 3502  static void getnewblk (int filedes, unsi | Line 3467  static void getnewblk (int filedes, unsi | 
 | nblock[offset + 1] = 0; | nblock[offset + 1] = 0; | 
 | nblock[OFFS] = offset / 256; | nblock[OFFS] = offset / 256; | 
 | nblock[OFFS + 1] = offset % 256; | nblock[OFFS + 1] = offset % 256; | 
|  |  | 
| lseek (filedes, hdr_offset + ((long) (freeblks) * BLOCKLEN), SEEK_SET); | gbl_write_block (g, freeblks, nblock); | 
| write (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | return; | return; | 
 |  |  | 
| Line 3515  static void getnewblk (int filedes, unsi | Line 3479  static void getnewblk (int filedes, unsi | 
 | nblock[NRBLK] = no_of_blks / 65536; | nblock[NRBLK] = no_of_blks / 65536; | 
 | nblock[NRBLK + 1] = no_of_blks % 65536 / 256; | nblock[NRBLK + 1] = no_of_blks % 65536 / 256; | 
 | nblock[NRBLK + 2] = no_of_blks % 256; | nblock[NRBLK + 2] = no_of_blks % 256; | 
|  |  | 
| lseek (filedes, hdr_offset + ROOT, SEEK_SET); | gbl_write_block (g, ROOT, nblock); | 
| write (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | *blknbr = no_of_blks; | *blknbr = no_of_blks; | 
 |  |  | 
 | for (;;) { |  | 
 |  |  | 
 | errno = 0; |  | 
 |  |  | 
 | lseek (filedes, hdr_offset + ((long) (no_of_blks) * BLOCKLEN), SEEK_SET); |  | 
 | write (filedes, nblock, BLOCKLEN); |  | 
 |  |  | 
 | if (errno == 0) break; |  | 
 |  |  | 
| panic (); | gbl_write_block (g, no_of_blks, nblock); | 
|  |  | 
| } |  | 
 |  |  | 
 | return; | return; | 
 |  |  | 
| Line 3661  static short int g_collate (char *t) | Line 3613  static short int g_collate (char *t) | 
 | /* | /* | 
 | * test whether 'str' is canonical | * test whether 'str' is canonical | 
 | */ | */ | 
 | //static short int g_numeric (char *str) |  | 
 | short g_numeric (char *str) | short g_numeric (char *str) | 
 | { | { | 
 | register int ptr = 0, ch; | register int ptr = 0, ch; | 
| Line 3742  void gbl_dump_stat(void) | Line 3693  void gbl_dump_stat(void) | 
 | int hit_pct; | int hit_pct; | 
 | unsigned long access_total; | unsigned long access_total; | 
 | unsigned long hit_total; | unsigned long hit_total; | 
|  | unsigned long mem_reads_total; | 
|  |  | 
|  | mem_reads_total = 0; | 
 | printf ("\r\nFreeM Global Statistics [PID %d]\r\n\r\n", pid); | printf ("\r\nFreeM Global Statistics [PID %d]\r\n\r\n", pid); | 
 |  |  | 
| printf ("%-20s%-10s%-12s%-20s%-10s%s\r\n", "GLOBAL", "USECT", "SLOW PTHCT", "AGE", "LAST BLK", "FILE"); | printf ("%-20s%-10s%-10s%-10s%-10s%-12s%-20s%-10s%s\r\n", "GLOBAL", "USECT", "READS", "WRITES", "MEMREADS", "SLOW PTHCT", "AGE", "LAST BLK", "FILE"); | 
| printf ("%-20s%-10s%-12s%-20s%-10s%s\r\n", "======", "=====", "==========", "===", "========", "===="); | printf ("%-20s%-10s%-10s%-10s%-10s%-12s%-20s%-10s%s\r\n", "======", "=====", "=====", "======", "========", "==========", "===", "========", "===="); | 
 |  |  | 
 | access_total = 0; | access_total = 0; | 
 | ct = 0; | ct = 0; | 
 | for (g = global_handles_head; g != NULL; g = g->next) { | for (g = global_handles_head; g != NULL; g = g->next) { | 
| printf ("%-20s%-10ld%-12ld%-20ld%-10ld%s\r\n", | printf ("%-20s%-10ld%-10ld%-10ld%-10ld%-12ld%-20ld%-10ld%s\r\n", | 
 | g->global_name, | g->global_name, | 
 | g->use_count, | g->use_count, | 
 |  | g->read_ops, | 
 |  | g->write_ops, | 
 |  | g->memory_reads, | 
 | g->cache_misses, | g->cache_misses, | 
 | g->age, | g->age, | 
 | g->last_block, | g->last_block, | 
 | g->global_path); | g->global_path); | 
 | ct++; | ct++; | 
 |  | mem_reads_total += g->memory_reads; | 
 | access_total += g->use_count; | access_total += g->use_count; | 
 | } | } | 
 | if (!ct) printf ("<no globals opened in this pid>\r\n"); | if (!ct) printf ("<no globals opened in this pid>\r\n"); | 
| Line 3769  void gbl_dump_stat(void) | Line 3726  void gbl_dump_stat(void) | 
 |  |  | 
 | printf ("\r\nTotal accesses:      %ld\r\n", access_total); | printf ("\r\nTotal accesses:      %ld\r\n", access_total); | 
 | printf ("Fast path hits       %ld\t(%d%%)\r\n", hit_total, hit_pct); | printf ("Fast path hits       %ld\t(%d%%)\r\n", hit_total, hit_pct); | 
| printf ("Fast path misses:    %ld\t(%d%%)\r\n", gbl_cache_misses, miss_pct); | printf ("Fast path misses:    %ld\t(%d%%)\r\n", gbl_cache_misses, miss_pct); | 
|  | printf ("Disk reads avoided:  %ld\r\n", mem_reads_total); | 
|  |  | 
 | } | } |