Diff for /freem/src/global_bltin.c between versions 1.22 and 1.24

version 1.22, 2025/04/13 04:22:43 version 1.24, 2025/04/28 14:52:54
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.22  2025/04/13 04:22:43  snw   *   Revision 1.24  2025/04/28 14:52:54  snw
  *   Fix snprintf calls   *   Temporarily revert global handler refactor and fix reference regression in xecline
  *  
  *   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  
  *   Eliminate as many warnings as possible while building with -Wall  
  *  
  *   Revision 1.13  2025/04/09 14:34:30  snw  
  *   Further work on global_bltin.c refactor  
  *  
  *   Revision 1.12  2025/04/09 00:43:07  snw  
  *   Exit with fatal error if a header mismatch found  
  *  
  *   Revision 1.11  2025/04/08 21:41:13  snw  
  *   Make insert, update, and splitp global handler functions take a ptr to a global_handle instead of a file descriptor  
  *  
  *   Revision 1.10  2025/04/08 20:00:56  snw  
  *   Global handler now uses a header file and maintains the last journaling transaction ID  
  *  
  *   Revision 1.9  2025/04/08 16:46:11  snw  
  *   Add global file header and offsets  
  *  
  *   Revision 1.8  2025/04/08 14:39:21  snw  
  *   Initial work on global handler refactor  
  *   *
  *   Revision 1.7  2025/03/24 04:13:11  snw   *   Revision 1.7  2025/03/24 04:13:11  snw
  *   Replace action macro dat with fra_dat to avoid symbol conflict on OS/2   *   Replace action macro dat with fra_dat to avoid symbol conflict on OS/2
Line 91 Line 49
 #include <fcntl.h>  #include <fcntl.h>
 #include <unistd.h>  #include <unistd.h>
 #include <string.h>  #include <string.h>
 #include <stdlib.h>  
 #include <errno.h>  #include <errno.h>
   
   
 #include "mpsdef.h"  #include "mpsdef.h"
 #include "journal.h"  
 #include "global_bltin.h"  
   
 global_handle *global_handles_head;  static void b_free (short filedes, unsigned long blknbr);
 unsigned long gbl_cache_misses = 0;  static void splitp (short filedes, char *block, long *addr, long *offs, unsigned long *blknbr);
 unsigned long gbl_cache_hits = 0;  static void update (short filedes, char *ins_key, long keyl);
   static void insert (int filedes, char *ins_key, long key_len, 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 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 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 (global_handle *g, unsigned long *blknbr);  static void getnewblk (int filedes, 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);
   
 #if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) && !defined(__OS2__)  #define ROOT 0L
 long time ();  
 #endif  
   
 inline long gbl_path(char *key, char *buf)  
 {  
     long savj;  
   
     register long int i;  
     register long int j;  
     register long int k;  
     register long int ch;  
      
     /* construct full UNIX filename */  
     savj = 0;  
     k = 0;  
     j = savj;  
   
     if (key[1] == '%' || key[1] == '$') {               /* %-globals and SSVN backing storage, no explicit path */  
           
         if (gloplib[0] != EOL) {  
               
             /* append % global access path */  
             while ((ch = buf[k++] = gloplib[j++]) != ':' && ch != EOL);   
   
         }   
   
     }  
     else if (key[1] != '/') {           /* no explicit path specified */  
           
         if (glopath[0] != EOL) {  
   
             /* append global access path */  
             while ((ch = buf[k++] = glopath[j++]) != ':' && ch != EOL);  
   
         }  
   
     }  
       
     if (k > 0) {  
   
         if (k == 1 || (k == 2 && buf[0] == '.')) {  
             k = 0;  
         }  
         else {  
             buf[k - 1] = '/';  
         }  
   
     }  
   
     savj = j;  
     i = 0;  
     j = 0;  
   
     while (key[i] != EOL) {  
   
         if ((buf[k] = key[i]) == DELIM) break;  
           
         if (buf[k] == '/') {  
               
             j = i;  
   
             if (k > i) {  
                 i = 0;  
                 j = 0;  
                 k = 0;  
   
                 continue;  
             }  
   
         }  
   
         i++;  
         k++;  
       
     }  
   
     buf[k] = NUL;                       /* NUL not EOL !!! */  
   
     return i;  
 } /* gbl_path() */  
   
 void gbl_cache_hit(global_handle *g)  
 {  
     g->cache_hits++;  
     gbl_cache_hits++;  
 } /* gbl_cache_hit() */  
   
 void gbl_cache_miss(global_handle *g)  
 {  
     g->fast_path = 0;  
     g->cache_misses++;  
     gbl_cache_misses++;  
 } /* gbl_cache_miss() */  
   
 int gbl_lock(global_handle *g, int type)  
 {  
     if (g->locked == TRUE || lonelyflag == TRUE) {  
         return TRUE;  
     }  
   
     locking (g->fd, type, 0L);  
     g->locked = TRUE;  
   
     return TRUE;  
 } /* gbl_lock() */  
   
 int gbl_unlock(global_handle *g)  
 {  
     if (g->locked == FALSE || lonelyflag == TRUE) {  
         return TRUE;  
     }  
   
     locking (g->fd, 0, 0L);  
     g->locked = FALSE;  
   
     return TRUE;  
 } /* gbl_unlock() */  
   
 void gbl_close(global_handle *g)  
 {  
     if (g->opened == TRUE) {  
         close (g->fd);  
   
         g->use_count = 0;  
         g->age = 0;  
         g->last_block = 0;  
         g->locked = FALSE;  
         g->opened = FALSE;  
     }  
 } /* gbl_close() */  
   
 void gbl_close_all(void)  
 {  
     global_handle *g;  
   
     for (g = global_handles_head; g != NULL; g = g->next) {  
         gbl_close (g);  
     }  
 } /* gbl_close_all() */  
   
 int gbl_write_initial_header(global_handle *g)  
 {  
     global_header hdr;  
     unsigned long old_position;  
     char m[5] = GBL_MAGIC;  
     char msg[256];  
       
     if (g->opened == FALSE) {  
         return FALSE;  
     }  
   
     memcpy (hdr.magic, m, 5);  
     hdr.format_version = GBL_FORMAT_VERSION;  
     strncpy (hdr.host_triplet, HOST, 40);  
     hdr.block_size = BLOCKLEN;  
     hdr.last_transaction_id = 0;  
     hdr.created = time (0L);  
     hdr.last_backup = -1;  
       
     gbl_lock (g, 1);  
     old_position = lseek (g->fd, 0, SEEK_CUR);  
     lseek (g->fd, 0, SEEK_SET);  
   
     if (write (g->fd, &hdr, sizeof (global_header)) == -1) {  
         snprintf (msg, sizeof (msg) - 1, "error %d writing global header for %s", errno, g->global_name);  
         m_fatal (msg);  
     }  
       
     lseek (g->fd, old_position, SEEK_SET);  
     gbl_unlock (g);  
   
     return TRUE;  
 } /* gbl_write_initial_header() */  
   
   
 int gbl_write_header(global_handle *g, global_header *hdr)  
 {  
     unsigned long old_position;  
     char msg[256];  
       
     if (g->opened == FALSE) {  
         return FALSE;  
     }  
   
     gbl_lock (g, 1);  
     old_position = lseek (g->fd, 0, SEEK_CUR);  
     lseek (g->fd, 0, SEEK_SET);  
   
     if (write (g->fd, hdr, sizeof (global_header)) == -1) {  
         snprintf (msg, sizeof (msg) - 1, "error %d writing global header for %s", errno, g->global_name);  
         m_fatal (msg);  
     }  
   
     lseek (g->fd, old_position, SEEK_SET);  
     gbl_unlock (g);  
   
     gbl_read_header (g, &g->header);  
       
     return TRUE;      
 } /* gbl_write_header() */  
   
 int gbl_read_header(global_handle *g, global_header *h)  
 {  
     unsigned long old_position;  
     char m[5] = GBL_MAGIC;  
   
       
     if (g->opened == FALSE) {  
         return GBL_HDR_NOTOPEN;  
     }  
   
     gbl_lock (g, 1);  
     old_position = lseek (g->fd, 0, SEEK_CUR);  
     lseek (g->fd, 0, SEEK_SET);  
   
     read (g->fd, h, sizeof (global_header));  
   
     lseek (g->fd, old_position, SEEK_SET);  
     gbl_unlock (g);  
   
     if (strncmp (h->magic, m, 5) != 0) {  
         return GBL_HDR_BADMAGIC;  
     }  
     if (h->format_version != GBL_FORMAT_VERSION) {  
         return GBL_HDR_BADVERSION;  
     }  
     if (h->block_size != BLOCKLEN) {  
         return GBL_HDR_BADBLOCKSIZE;  
     }  
   
     return GBL_HDR_OK;                            
 } /* gbl_read_header() */  
   
 int gbl_update_tid(global_handle *g)  
 {  
     global_header h;  
   
     if (gbl_read_header (g, &h) != GBL_HDR_OK) {  /* end of line symbol in global module is 30, which is a code not */
         return FALSE;  /* otherwise used in subscripts                                   */
     }  #define g_EOL 30
   
     h.last_transaction_id = jnl_tran_id;  #define EOL1 EOL
   
     return gbl_write_header (g, &h);          /* numerics (('.'<<1)&037)==28 ; (('-'<<1)&037)==26; */
 } /* gbl_update_tid() */  #define POINT 28
   #define MINUS 26
 int gbl_create(global_handle *g)  
 {  /* ALPHA and OMEGA are dummy subscripts in $order processing */
     while (1) {  /* ALPHA sorts before all other subscripts                   */
         errno = 0;  /* OMEGA sorts after all other subscripts                    */
   /* e.g. ("abc") -> "abc",OMEGA ; ("abc","") -> "abc",ALPHA   */
         if ((g->fd = creat (g->global_path, 0666)) != -1) break;  #define OMEGA 29
   #define ALPHA 31
         if (errno == EMFILE || errno == ENFILE) {  
             gbl_close_all ();  /* length of blocks. status bytes defined as offset to blocklength */
             continue;  /*      BLOCKLEN 1024           is defined in mpsdef0 include file */
         }  #define DATALIM (BLOCKLEN-11)
   #define LLPTR   (BLOCKLEN-10)
         return PROTECT;  #define NRBLK    LLPTR
     }  #define COLLA   (BLOCKLEN- 7)
   #define RLPTR   (BLOCKLEN- 6)
     g->opened = TRUE;  #define FREE     RLPTR
     g->age = time (0L);  #define BTYP    (BLOCKLEN- 3)
     g->last_block = 0;  #define OFFS    (BLOCKLEN- 2)
     g->use_count = 1;  
     g->fast_path = 0;  /* length of blockpointers in bytes */
       #define PLEN     3
     gbl_write_initial_header (g);  
       #define EMPTY    0
     return OK;  #define FBLK     1
 } /* gbl_create() */  #define POINTER  2
   #define BOTTOM   6
 short gbl_open(global_handle *g, short action)  #define DATA     8
 {  
     int result;  
       
     if (g->opened == FALSE) {  
         gbl_cache_miss (g);  
         while (1) {  
             errno = 0;  
             g->fd = open (g->global_path, 2);  
               
             if (g->fd != -1) break;  
               
             switch (errno) {              
                 case EINTR:  
                     continue;  
                       
                 case EMFILE:  
                 case ENFILE:  
                     gbl_close_all ();  
                     continue;  
             }  
               
             break;  
         }  
           
         if (g->fd == -1) {  
             g->use_count = 0;  
             g->age = 0;  
             g->last_block = 0;  
             g->locked = FALSE;  
             g->opened = FALSE;  
         }  
         else {  
             g->opened = TRUE;  
             result = gbl_read_header (g, &g->header);              
               
             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;  
             }  
             else {                  
                 gbl_close (g);  
                 set_io (UNIX);  
                   
                 switch (result) {  
                       
                     case GBL_HDR_BADMAGIC:  
                         fprintf (stderr, "gbl_open:  bad magic value in %s [FATAL]\n", g->global_name);  
                         exit (1);  
                         break;  
   
                     case GBL_HDR_BADVERSION:  
                         fprintf (stderr, "gbl_open:  global version is %d in %s (must be %d) [FATAL]\n", g->header.format_version, g->global_name, GBL_FORMAT_VERSION);  
                         exit (1);  
                         break;  
   
                 }  
                           
                 return FALSE;  
             }  
         }  
     }  
   
     return g->opened;  
       
 } /* 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, g->header.block_size);  
         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 *g;  
     char global_name[256];  
     int i;  
     struct stat dinf;              
       
     i = 0;  
     while (key[i] != EOL) {  
         if ((global_name[i] = key[i]) == DELIM) break;  
   
         i++;  
     }  
     global_name[i] = NUL;  
   
       
     for (g = global_handles_head; g != NULL; g = g->next) {  
         if (strncmp (g->global_name, global_name, 256) == 0) {  
             g->use_count++;  
             if (!lonelyflag) {  
                 g->fast_path = 0;  
             }  
   
             fstat (g->fd, &dinf);  
             if (g->age > dinf.st_mtime) {  
                 g->fast_path = 2;  
                 return g;  
             }  
   
             g->age = time (0L);  
             g->fast_path = 0;  
               
             return g;  
         }  
     }  
     g = (global_handle *) malloc (sizeof (global_handle));  
     NULLPTRCHK(g,"gbl_open");  
   
     g->use_count = 1;  
     g->locked = FALSE;  
     g->age = time (0L);  
     g->last_read_time = 0;  
     g->last_block = 0;  
     g->opened = FALSE;  
     g->fd = 0;  
     g->fast_path = -1;  
     g->cache_misses = 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);      
     gbl_path (key, g->global_path);  
       
     g->next = global_handles_head;  
     global_handles_head = g;  
   
     return g;      
 } /* gbl_handle() */  
   
   #if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) && !defined(__OS2__)
    long time ();
   #endif
   
 /* globals management */  /* globals management */
           
Line 674  global_handle *gbl_handle(char *key) Line 185  global_handle *gbl_handle(char *key)
  * the file is *not* closed on return. since access is regulated by the   * the file is *not* closed on return. since access is regulated by the
  * locking mechanism, that will not spell trouble.   * locking mechanism, that will not spell trouble.
  */   */
    
 void global_bltin (short action, char *key, char *data)  void global_bltin (short action, char *key, char *data)
 {  {
   
     global_handle *g;  
   
     unsigned long hdr_offset;  
       
     /* these must be static variables */      /* these must be static variables */
   
       static short filedes;               /* filedescr for global access */
     static char filnam[256];            /* name of global/unix file */      static char filnam[256];            /* name of global/unix file */
   
     /* the following vars may be */      /* the following vars may be */
     /* static or dynamic */      /* static or dynamic */
   
     static unsigned long blknbr;        /* block number */      static unsigned long blknbr;        /* block number */
       static unsigned long oldblk;
     static unsigned long newblk;      static unsigned long newblk;
     static unsigned long other;      static unsigned long other;
     static long j1;      static long j1;
     static long limit;      static long limit;
     static short typ;                   /* block type */      static short typ;                   /* block type */
     static long keyl;                   /* length of compacted key */      static long keyl,                   /* length of compacted key */
     static long datal;                  /* length of data */                  datal,                  /* length of data */
     static long olddatal;                  olddatal,
     static long offset;                  offset,
     static long found;                  found,
     static long addr;                   /* address of key in 'block' */                  addr,                   /* address of key in 'block' */
     static long needed;                 /* new bytes needed to ins. stuff */                  needed,                 /* new bytes needed to ins. stuff */
     static long ret_to;                 /* return code */                  ret_to,                 /* return code */
     static long kill_again;                  kill_again;
     static char key1[256];      static char key1[256];
     static char tmp1[256];              /* intermediate storage for op= */      static char tmp1[256];              /* intermediate storage for op= */
     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 */
   
       struct stat dinf;                   /* get modification date */
   
       long    savj,
       savch;                      /* saved j and ch for multiple pathes */
       register long int i,
       j,
       k,
       ch;
       long    pathscan;                   /* flag for repeated scan of pathlist setting an undef global */
   
     int iresult;  
       
     register long int i;  
     register long int j;  
     register long int k;  
     register long int ch;  
   
     j = 0;      
     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++;
                 }                  }
             }              }
               
         }          }
     }      }
   
   
     if (action == getnext) {      if (action == getnext) {
   
         getnflag = TRUE;          getnflag = TRUE;
         varnam[0] = EOL;          varnam[0] = EOL;
                   
Line 834  void global_bltin (short action, char *k Line 366  void global_bltin (short action, char *k
         }          }
     }      }
   
     g = gbl_handle (key);          if (v22ptr) {
     i = gbl_path (key, filnam);  
           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;
           }
       }
   
       /* construct full UNIX filename */
       savj = 0;
       savch = ch = EOL;
       pathscan = TRUE;
       nextpath:
       k = 0;
       j = savj;
   
       if (key[1] == '%' || key[1] == '$') {               /* %-globals and SSVN backing storage, no explicit path */
           
           if (gloplib[0] != EOL) {
               
               /* append % global access path */
               while ((ch = filnam[k++] = gloplib[j++]) != ':' && ch != EOL); 
   
           } 
   
       }
       else if (key[1] != '/') {           /* no explicit path specified */
           
           if (glopath[0] != EOL) {
   
               /* append global access path */
               while ((ch = filnam[k++] = glopath[j++]) != ':' && ch != EOL);
   
           }
   
       }
   
       if (savj == 0 && ch == EOL) pathscan = FALSE;               /* one path only: inhibit search */
       
       if (k > 0) {
   
           if (k == 1 || (k == 2 && filnam[0] == '.')) {
               k = 0;
           }
           else {
               filnam[k - 1] = '/';
           }
   
       }
   
       savch = ch;
       savj = j;
       i = 0;
       j = 0;
   
       while (key[i] != EOL) {
   
           if ((filnam[k] = key[i]) == DELIM) break;
           
           if (filnam[k] == '/') {
               
               j = i;
   
               if (k > i) {
                   i = 0;
                   j = 0;
                   k = 0;
   
                   continue;
               }
   
           }
   
           i++;
           k++;
       
       }
   
       filnam[k] = NUL;                    /* NUL not EOL !!! */
   
       /* if a unix directory is specified, reposition '^' */
       /* '^/usr/test' becomes '/usr/^test'                */
       if (j > 0) {
   
           for (k = 0; k < j; k++) {
               filnam[k] = filnam[k + 1];
           }
       
           filnam[j] = '^';
   
       }
   
     /* compact key to internal format: characters are shifted left */      /* compact key to internal format: characters are shifted left */
     /* delimiters become LSB of previous character                 */      /* delimiters become LSB of previous character                 */
     /* test subscripts for being numeric or not                    */      /* test subscripts for being numeric or not                    */
Line 898  void global_bltin (short action, char *k Line 527  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 970  void global_bltin (short action, char *k Line 601  void global_bltin (short action, char *k
   
     compactkey[k] = g_EOL;      compactkey[k] = g_EOL;
   
       /* look whether file is already open */
       tryfast = FALSE;
       ch = usage[i = j = inuse];
       
       while (i < NO_GLOBLS) {
           
           k = 0;
           
           while (filnam[k] == oldfil[i][k]) {
   
               if (filnam[k++] == NUL) {
   
                   filedes = olddes[i];
   
                   if (inuse == i && action == get_sym) {
                       
                       tryfast = TRUE;
                       
                       if (usage[i] != (-1)) usage[i]++;
                       if (lonelyflag) goto tfast2;
                       
                       fstat (filedes, &dinf);
                       
                       if (g_ages[i] > dinf.st_mtime) goto tfast2;
                       
                       g_ages[i] = time (0L);
                       
                       goto tfast0;
   
                   }
   
                   inuse = i;
   
                   if (usage[i] != (-1)) usage[i]++;
                   
                   goto lock;
               }
   
           }
   
           if (ch < 0 || (usage[i] >= 0 && usage[i] < ch)) ch = usage[j = i];
           
           if (i++ == inuse) {
               inuse = (-1);
               i = 0;
           }
   
       }
   
       inuse = j;
       usage[j] = 1;
   
       /* close previous file */
       if ((filedes = olddes[j]) > 0) {
           close (filedes);
           olddes[j] = 0;
       }
   
       strcpy (oldfil[j], filnam);         /* save current filename */
   
 reopen:  reopen:
   
     if (!gbl_open (g, action)) {      for (;;) {
   
           errno = 0;
           
           if ((filedes = open (filnam, 2)) != -1) break;
           if (errno == EINTR) continue;
   
           if (errno == EMFILE || errno == ENFILE) {       /* too many open files now */
               close_all_globals ();
               
               continue;
           }
   
           break;
       }
   
       if (filedes == -1) {
   
           usage[inuse] = 0;
           oldfil[inuse][0] = NUL;
           olddes[inuse] = 0;
           g_ages[inuse] = 0;
           
           if ((pathscan || errno != ENOENT) && (savch != EOL)) goto nextpath;             /* try next access path */
           
         /* file not found */          /* file not found */
         if (action != set_sym) {          if (action != set_sym) {
                           
Line 1006  reopen: Line 720  reopen:
             merr_raise (PROTECT);              merr_raise (PROTECT);
             return;              return;
         }          }
           
           if (pathscan) {
               savj = 0;
               savch = ch = EOL;
               pathscan = FALSE;
   
               goto nextpath;
           }
   
         if (setop) {          if (setop) {
                           
             tmp1[0] = EOL;              tmp1[0] = EOL;
Line 1036  reopen: Line 758  reopen:
         block[NRBLK + 2] = ROOT + 1;    /* nr. of blocks */          block[NRBLK + 2] = ROOT + 1;    /* nr. of blocks */
   
         /* create file, write_lock it and initialize root block */          /* create file, write_lock it and initialize root block */
         gbl_lock (g, 1);          for (;;) {
   
         if ((iresult = gbl_create (g)) != OK) {              errno = 0;
             merr_raise (iresult);              
               if ((filedes = creat (filnam, 0666)) != -1) break;
   
               if (errno == EMFILE || errno == ENFILE) {
                   close_all_globals ();
                   continue;
               }
   
               merr_raise (PROTECT);
             return;              return;
         }                  }
   
         gbl_write_block (g, ROOT, block);          if (lonelyflag == FALSE) locking (filedes, 1, 0L);
           
           for (;;) {
               
               errno = 0;
           
               lseek (filedes, ROOT * BLOCKLEN, 0);
               write (filedes, block, BLOCKLEN);
                   
               if (errno == 0) break;
           
               panic ();
           }
   
         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 1055  reopen: Line 797  reopen:
         block[BTYP] = DATA;             /* type */          block[BTYP] = DATA;             /* type */
         block[OFFS] = i / 256;          block[OFFS] = i / 256;
         block[OFFS + 1] = i % 256;          block[OFFS + 1] = i % 256;
   
         gbl_write_block (g, ROOT + 1, block);  
                   
         gbl_close (g);          for (;;) {
         gbl_unlock (g);  
         gbl_open (g, action);              errno = 0;
               write (filedes, block, BLOCKLEN);
               
               if (errno == 0) break;
               
               lseek (filedes, (ROOT + 1L) * BLOCKLEN, 0);
               panic ();
   
           }
   
           close (filedes);
           
           if (lonelyflag == FALSE) locking (filedes, 0, 0L);      /* unlock */
           
         /* close new file, so other users can find it */          /* close new file, so other users can find it */
         return;          return;
     }      }
   
       olddes[inuse] = filedes;            /* save current filedescriptor */
   
     /* request global for exclusive use                            */      /* request global for exclusive use                            */
     /* odd numbered actions get read access (get_sym,data,fra_order) 3 */      /* odd numbered actions get read access (get_sym,data,fra_order) 3 */
     /* even ones read/write access          (set_sym,kill_sym)   1 */      /* even ones read/write access          (set_sym,kill_sym)   1 */
   
 /* temporarily disabled      lock:
    lock:  
 */  
   
     if (action == get_sym) {      if (action == get_sym) {
   
 tfast0:  tfast0:
         gbl_lock (g, 3);  
                   if (lonelyflag == FALSE) locking (filedes, 3, 0L);        
         if (g->fast_path > 0) {          if (tryfast) goto tfast1;               /* try again last block */
             goto tfast1;                /* try again last block */  
         }  
                   
         blknbr = g->last_block = ROOT;          /* start with ROOT block */          blknbr = oldblk = ROOT;         /* start with ROOT block */
                   
         for (;;) {          for (;;) {
         tfast1:  
             gbl_read_block (g, blknbr, block);  
   
 /* temporarily disabled  
    tfast2:  
 */  
             if ((typ = block[BTYP]) == DATA) {  /* scan data block: here we test for equality only */  
                 offset = UNSIGN (block[OFFS]) * 256 +              
                     UNSIGN (block[OFFS + 1]);  
                 j = UNSIGN (block[0]);  
                 i = 0;  
   
                 stcpy0 (key1, &block[2], j);    /* get first key */  tfast1:
   
               lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
               read (filedes, block, BLOCKLEN);
   
   
   tfast2:
   
           if ((typ = block[BTYP]) == DATA) {      /* scan data block: here we test for equality only */
   
               offset = UNSIGN (block[OFFS]) * 256 +            
               UNSIGN (block[OFFS + 1]);
               j = UNSIGN (block[0]);
               i = 0;
   
               stcpy0 (key1, &block[2], j);        /* get first key */
                           
                 ch = keyl;              /* ch is a register! */              ch = keyl;          /* ch is a register! */
                 while (i < offset) {                                  
                     j = UNSIGN (block[i++]);    /* length of key - offset */              while (i < offset) {
                     k = UNSIGN (block[i++]);    /* offset into previous entry */              
                                       j = UNSIGN (block[i++]);        /* length of key - offset */
                     j += k;                  k = UNSIGN (block[i++]);        /* offset into previous entry */
                       
                     while (k < j) key1[k++] = block[i++];               /* get key */  #ifdef VERSNEW
                       
                     if (j != ch) {      /* keys have different length */                                          stcpy0 (&key0[k], &block[i], j);
                         i += UNSIGN (block[i]);                  i += j;
                         i++;                  j += k;
                           
                         continue;                          #else
                     }  
                                       j += k;
                     j = ch;              
                                       while (k < j) key1[k++] = block[i++];           /* get key */
                     do {  
                         j--;  #endif /* VERSNEW */
                     } while (compactkey[j] == key1[j]);         /* compare keys */  
                                                           if (j != ch) {  /* keys have different length */
                     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++;                /* skip data */                                          i++;
                 }  
                                       continue;
                 /* fast access failed. try normal path */  
                 if (tryfast) {  
                     gbl_cache_miss (g);  
                     goto tfast0;  
                 }                  }
   
                 merr_raise (M7);                  /* key1[j]=g_EOL; */
                 data[0] = EOL;                  j = ch;
                   
                 goto quit;              /* variable not found */  
             }   
             else {  
                                   
                 if (g->fast_path > 0) {                  do {
                     gbl_cache_miss (g);                      j--;
                     goto tfast0;                  } while (compactkey[j] == key1[j]);             /* compare keys */
                 }  
                                   
                 if (typ == EMPTY) {  
                                       if (j < 0) {
                     if (blknbr == ROOT) {  
                         gbl_close (g);  
                         goto reopen;  
                     }  
                                           
                     merr_raise (DBDGD);                      k = UNSIGN (block[i++]);
                       stcpy0 (data, &block[i], k);        /* get value */
                       data[k] = EOL1;     /* append EOL */
   
                     goto quit;                      goto quit;
                       
                 }                  }
                   
                   i += UNSIGN (block[i]);
                   i++;            /* skip data */
   
             }              }
   
               /* fast access failed. try normal path */
               if (tryfast) {
                   tryfast = FALSE;
                   goto tfast0;
               }
   
               merr_raise (M7);
               data[0] = EOL;
                           
             scanpblk (block, &addr, &found);              goto quit;          /* variable not found */
                       } 
             addr += UNSIGN (block[addr]) + 2;   /* skip key */          else {
                       
             if ((blknbr = UNSIGN (block[addr]) * 65536 + UNSIGN (block[addr + 1]) * 256 + UNSIGN (block[addr + 2])) == g->last_block) {              if (tryfast) {
                   tryfast = FALSE;
                   goto tfast0;
               }
   
               if (typ == EMPTY) {
                   
                   if (blknbr == ROOT) {
                       close (filedes);
                       goto reopen;
                   }
   
                 merr_raise (DBDGD);                  merr_raise (DBDGD);
                 goto quit;                  goto quit;
   
             }              }
   
             addr += PLEN;               /* skip data */          }
             g->last_block = blknbr;  
             g->fast_path = 1;          scanpblk (block, &addr, &found);
   
           addr += UNSIGN (block[addr]) + 2;       /* skip key */
           
           if ((blknbr = UNSIGN (block[addr]) * 65536 + UNSIGN (block[addr + 1]) * 256 + UNSIGN (block[addr + 2])) == oldblk) {
               merr_raise (DBDGD);
               goto quit;
           }
   
           addr += PLEN;           /* skip data */
           oldblk = blknbr;
                   
             if (merr () == INRPT) goto quit;          if (merr () == INRPT) goto quit;
   
         }          }
     }                                   /* end of get_sym */      }                                   /* end of get_sym */
   
     gbl_lock (g, action & 01 ? 3 : 1);  
           if (lonelyflag == FALSE) locking (filedes, (action & 01 ? 3 : 1), 0L);
   
     /* 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) {
                   
         /* note : UNIX does not tell other jobs that a file has been unlinked */              lseek (filedes, ROOT, 0);
   
           /* 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    */
         block[BTYP] = EMPTY;                      write (filedes, block, BLOCKLEN);
           
         gbl_write_block (g, ROOT, block);          if (lonelyflag == FALSE) locking (filedes, 0, 0L);      /* unlock */
           
         gbl_unlock (g);          close (filedes);
         gbl_close (g);          
           olddes[inuse] = 0;
           oldfil[inuse][0] = NUL;
           usage[inuse] = 0;
                   
         unlink (filnam);          unlink (filnam);
                   
Line 1207  tfast0: Line 988  tfast0:
 k_again:                                /* entry point for repeated kill operations */  k_again:                                /* entry point for repeated kill operations */
   
     /* scan tree for the proper position of key */      /* scan tree for the proper position of key */
     blknbr = g->last_block = ROOT;              /* start with ROOT block */      blknbr = oldblk = ROOT;             /* start with ROOT block */
     trx = (-1);      trx = (-1);
   
     for (;;) {      for (;;) {
Line 1219  k_again:    /* entry point for repeated Line 1000  k_again:    /* entry point for repeated
   
         traceblk[trx] = blknbr;          traceblk[trx] = blknbr;
         traceadr[trx] = 0;          traceadr[trx] = 0;
           
         gbl_read_block (g, blknbr, block);          lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
           read (filedes, block, BLOCKLEN);
           
         typ = block[BTYP];          typ = block[BTYP];
                   
         if (typ == DATA) {          if (typ == DATA) {
Line 1231  k_again:    /* entry point for repeated Line 1014  k_again:    /* entry point for repeated
         if (typ == EMPTY) {          if (typ == EMPTY) {
   
             if (blknbr == ROOT) {              if (blknbr == ROOT) {
                 gbl_close (g);                  close (filedes);
                 goto reopen;                  goto reopen;
             }              }
   
Line 1245  k_again:    /* entry point for repeated Line 1028  k_again:    /* entry point for repeated
         addr += UNSIGN (block[addr]);          addr += UNSIGN (block[addr]);
         addr += 2;                      /* skip key */          addr += 2;                      /* skip key */
                   
         if ((blknbr = UNSIGN (block[addr]) * 65536 + UNSIGN (block[addr + 1]) * 256 + UNSIGN (block[addr + 2])) == g->last_block) {          if ((blknbr = UNSIGN (block[addr]) * 65536 + UNSIGN (block[addr + 1]) * 256 + UNSIGN (block[addr + 2])) == oldblk) {
             merr_raise (DBDGD);              merr_raise (DBDGD);
             goto quit;              goto quit;
         }          }
   
         addr += PLEN;                   /* skip data */          addr += PLEN;                   /* skip data */
         g->last_block = blknbr;          oldblk = blknbr;
         g->fast_path = 1;  
     }      }
   
     traceadr[trx] = addr;      traceadr[trx] = addr;
Line 1263  k_again:    /* entry point for repeated Line 1045  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 1289  k_again:    /* entry point for repeated Line 1071  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 1169  s10:
   
                 }                  }
   
                 gbl_write_block (g, blknbr, block);                  lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                   write (filedes, block, BLOCKLEN);
   
                 if (traceadr[trx] == 0) update (g, compactkey, keyl);                  if (traceadr[trx] == 0) update (filedes, compactkey, keyl);
   
                 break;                  break;
             }              }
Line 1432  s10: Line 1214  s10:
   
                 }                   } 
                 else {                                    else {                  
                       /* if (j1<0) */
                     /* we need more space */                       /* we need more space */ 
   
                     if ((offset - j1) > DATALIM) {                      if ((offset - j1) > DATALIM) {
Line 1441  s10: Line 1224  s10:
                         goto splitd;                          goto splitd;
                     }                      }
   
                 s20:  s20:
                                           
                     i = offset;                      i = offset;
                     k = addr + olddatal;                      k = addr + olddatal;
Line 1474  s10: Line 1257  s10:
             }              }
           
             stcpy0 (&block[++addr], data, (long) datal);              stcpy0 (&block[++addr], data, (long) datal);
               lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
             gbl_write_block (g, blknbr, block);              write (filedes, block, BLOCKLEN);
               
             break;              break;
   
   
Line 1501  s10: Line 1283  s10:
   
                 /* 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]))) {
                       
                         gbl_read_block (g, blknbr, block);                          lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                           read (filedes, block, BLOCKLEN);
                         j1 = UNSIGN (block[0]);                          j1 = UNSIGN (block[0]);
                                           
                         i = 0;                          i = 0;
Line 1588  s10: Line 1371  s10:
                                   
                     goto quit;                      goto quit;
                 }       /* no next block */                  }       /* no next block */
                   
                 gbl_read_block (g, blknbr, block);                  lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                   read (filedes, block, BLOCKLEN);
                 scandblk (block, &addr, &found);                  scandblk (block, &addr, &found);
   
             }               } 
Line 1636  s10: Line 1420  s10:
                                   
                 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 1669  s10: Line 1453  s10:
                 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 1745  s10: Line 1529  s10:
                         goto quit;              /* no next block */                          goto quit;              /* no next block */
                     }                      }
   
                     gbl_read_block (g, blknbr, block);                      lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                       read (filedes, 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 1768  s10: Line 1553  s10:
                     goto quit;          /* no next block */                      goto quit;          /* no next block */
                 }                  }
   
                 gbl_read_block (g, blknbr, block);                  lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                   read (filedes, block, BLOCKLEN);
                                   
                 addr = 0;                  addr = 0;
             }               } 
Line 1816  s10: Line 1602  s10:
                     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 1893  s10: Line 1679  s10:
                         }                          }
   
                         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 1938  s10: Line 1724  s10:
   
         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 1977  s10: Line 1763  s10:
   
                         other = traceblk[--trx];                          other = traceblk[--trx];
                         addr = traceadr[trx];                          addr = traceadr[trx];
                           
                         gbl_read_block (g, other, block);                          lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
                           read (filedes, 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;
   
                     gbl_read_block (g, blknbr, block);                      lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                       read (filedes, 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 2089  s10: Line 1877  s10:
                 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) {
   
                         gbl_read_block (g, left, block0);                          lseek (filedes, (long) left * (long) (BLOCKLEN), 0);
                           read (filedes, 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];
                           
                         gbl_write_block (g, left, block0);                          lseek (filedes, (long) left * (long) (BLOCKLEN), 0);
                           write (filedes, block0, BLOCKLEN);
   
                     }                      }
   
                     if (right) {                      if (right) {
                           
                         gbl_read_block (g, right, block0);                          lseek (filedes, (long) right * (long) (BLOCKLEN), 0);
                           read (filedes, 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];
                           
                         gbl_write_block (g, right, block0);                          lseek (filedes, (long) right * (long) (BLOCKLEN), 0);
                           write (filedes, block0, BLOCKLEN);
   
                     }                      }
   
                     b_free (g, blknbr); /* modify free list */                      b_free (filedes, blknbr);   /* modify free list */
                                           
                     /* delete pointer */                      /* delete pointer */
                     /**************************/                      /**************************/
Line 2138  s10: Line 1930  s10:
                         blknbr = traceblk[--trx];                          blknbr = traceblk[--trx];
                         addr = traceadr[trx];                          addr = traceadr[trx];
   
                         gbl_read_block (g, blknbr, block);                          lseek (filedes, (long) (blknbr) * (long) (BLOCKLEN), 0);
                           read (filedes, 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 2150  s10: Line 1943  s10:
   
                             if (blknbr == ROOT) {       /* global went empty */                              if (blknbr == ROOT) {       /* global went empty */
   
                                   lseek (filedes, 0L, 0);
                                                   
                                 /* 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    */
                                 gbl_write_block (g, 0L, block);                                  write (filedes, block, BLOCKLEN);
                                   close (filedes);
                                 gbl_close (g);  
                                 unlink (filnam);                                  unlink (filnam);
                           
                                 gbl_unlock (g);                                  if (lonelyflag == FALSE) locking (filedes, 0, 0L);      /* unlock */
   
                                 olddes[inuse] = 0;                                  olddes[inuse] = 0;
                                 oldfil[inuse][0] = NUL;                                  oldfil[inuse][0] = NUL;
Line 2183  s10: Line 1975  s10:
                                                   
                         for (i = offset; i < offset + freecnt; block[i++] = 0);                          for (i = offset; i < offset + freecnt; block[i++] = 0);
   
                         gbl_write_block (g, blknbr, block);                          lseek (filedes, (long) (blknbr) * (long) (BLOCKLEN), 0);
                           write (filedes, block, BLOCKLEN);
   
                         if (addr == 0) {        /* update of pointer */                          if (addr == 0) {        /* update of pointer */
                             traceadr[trx] = 0;                              traceadr[trx] = 0;
                                                           
                             update (g, &block[2], (long) UNSIGN (block[0]));                              update (filedes, &block[2], (long) UNSIGN (block[0]));
                         }                          }
   
                         trx = trxsav;                          trx = trxsav;
Line 2213  s10: Line 2006  s10:
                     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 (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                 gbl_write_block (g, blknbr, block);                  write (filedes, block, BLOCKLEN);
   
                 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 (filedes, &block[2], (long) UNSIGN (block[0]));
                 }                  }
             }              }
   
Line 2243  s10: Line 2035  s10:
   
             break;              break;
   
         zinv:  zinv:
   
             {              {
                 long    len;                  long    len;
Line 2257  s10: Line 2049  s10:
                         data[0] = EOL1;                          data[0] = EOL1;
                         goto quit;                          goto quit;
                     }                   /* no previous block */                      }                   /* no previous block */
                       
                     gbl_read_block (g, blknbr, block);                      lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                       read (filedes, block, BLOCKLEN);
                                           
                     addr = UNSIGN (block[OFFS]) * 256 +                      addr = UNSIGN (block[OFFS]) * 256 +
                         UNSIGN (block[OFFS + 1]);                      UNSIGN (block[OFFS + 1]);
   
                 }                  }
   
Line 2336  s10: Line 2129  s10:
                 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 2382  s10: Line 2175  s10:
   
         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) {                      if (ch & 01) {
                     icnt++;                          icnt++;
                 }                      }
                                   
             }                  }
                                   
             len = i - 1;                  len = i - 1;
             i = 0;                  i = 0;
                                   
             while (i < addr) {          /* compute offset complete key */                  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 */
                     }                          }
   
                     gbl_read_block (g, blknbr, block);                          lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                           read (filedes, 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 2528  quit: Line 2346  quit:
           
     /* clean things up */      /* clean things up */
   
     lseek (g->fd, hdr_offset + ROOT, SEEK_SET);      lseek (filedes, ROOT, 0);
     gbl_unlock (g);  
           if (lonelyflag == FALSE) locking (filedes, 0, 0L);  /* unlock */
   
     return;      return;
   
   
Line 2541  splitd:    /* split data block in two se Line 2360  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, &newblk);     /* get a new block */      getnewblk (filedes, &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 2549  splitd:    /* split data block in two se Line 2368  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 2559  splitd:    /* split data block in two se Line 2378  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;
   
         gbl_write_block (g, blknbr, block);          lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
           write (filedes, block, BLOCKLEN);
                   
         block[RLPTR] = right;          block[RLPTR] = right;
         block[RLPTR + 1] = right1;          block[RLPTR + 1] = right1;
Line 2571  splitd:    /* split data block in two se Line 2391  splitd:    /* split data block in two se
         addr = 0;          addr = 0;
         blknbr = newblk;          blknbr = newblk;
                   
         insert (g, compactkey, keyl, newblk);          insert (filedes, compactkey, keyl, newblk);
                   
         /* up-date LL-PTR of RL-block */          /* up-date LL-PTR of RL-block */
         if ((other = right * 65536 + right1 * 256 + right2)) {          if ((other = right * 65536 + right1 * 256 + right2)) {
                   
             char    block0[BLOCKLEN];              char    block0[BLOCKLEN];
   
             gbl_read_block (g, other, block0);              lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
               read (filedes, 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;
                   
             gbl_write_block (g, other, block0);              lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
                           write (filedes, block0, BLOCKLEN);
           
         }          }
                   
         goto spltex;          goto spltex;
Line 2602  splitd:    /* split data block in two se Line 2424  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;
   
         gbl_write_block (g, blknbr, block);          lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
           write (filedes, 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 2614  splitd:    /* split data block in two se Line 2437  splitd:    /* split data block in two se
         blknbr = newblk;          blknbr = newblk;
         traceadr[trx] = (-1);           /* inhibit second update of pointers */          traceadr[trx] = (-1);           /* inhibit second update of pointers */
                   
         insert (g, compactkey, keyl, newblk);          insert (filedes, compactkey, keyl, newblk);
                   
         if (addr < 3) {                 /* update of pointer */          if (addr < 3) {                 /* update of pointer */
             traceadr[trx] = 0;              traceadr[trx] = 0;
                           
             update (g, compactkey, keyl);              update (filedes, compactkey, keyl);
         }          }
   
         /* 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 2715  splitd:    /* split data block in two se Line 2538  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 2727  splitd:    /* split data block in two se Line 2550  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;
   
             gbl_write_block (g, newblk, block0);              lseek (filedes, (long) (newblk) * (long) (BLOCKLEN), 0);
               write (filedes, block0, BLOCKLEN);
                   
             offset = limit;              offset = limit;
             /* insert new block in pointer structure */              /* insert new block in pointer structure */
                   
             insert (g, &block0[2], (long) UNSIGN (block0[0]), newblk);              insert (filedes, &block0[2], (long) UNSIGN (block0[0]), newblk);
                   
             /* up-date LL-PTR of RL-block */              /* up-date LL-PTR of RL-block */
             if (other != 0) {              if (other != 0) {
   
                 gbl_read_block (g, other, block0);                  lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
                   read (filedes, 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;
                   
                 gbl_write_block (g, other, block0);                  lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
                   write (filedes, block0, BLOCKLEN);
   
             }              }
   
Line 2752  splitd:    /* split data block in two se Line 2578  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 2764  splitd:    /* split data block in two se Line 2590  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;
   
             gbl_write_block (g, blknbr, block);              lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
                           write (filedes, block, BLOCKLEN);
             stcpy0 (block, block0, (long) BLOCKLEN);              stcpy0 (block, block0, (long) BLOCKLEN);
   
             traceadr[trx] = (addr -= limit);              traceadr[trx] = (addr -= limit);
             traceblk[trx] = (blknbr = newblk);              traceblk[trx] = (blknbr = newblk);
                           
             /* insert new block in pointer structure */              /* insert new block in pointer structure */
             insert (g, &block0[2], (long) UNSIGN (block0[0]), newblk);              insert (filedes, &block0[2], (long) UNSIGN (block0[0]), newblk);
                           
             /* up-date LL-PTR of RL-block */              /* up-date LL-PTR of RL-block */
             if (other != 0) {              if (other != 0) {
   
                 gbl_read_block (g, other, block0);                  lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
                   read (filedes, 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;
                   
                 gbl_write_block (g, other, block0);                  lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
                   write (filedes, block0, BLOCKLEN);
   
             }              }
   
Line 2810  spltex: Line 2638  spltex:
  *   '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
  */   */
 static void splitp (global_handle *g, char *block, long *addr, long *offs, unsigned long *blknbr)         static void splitp (short filedes, char *block, long *addr, long *offs, unsigned long *blknbr)  
 {  {
   
     char block0[BLOCKLEN];      char block0[BLOCKLEN];
Line 2818  static void splitp (global_handle *g, ch Line 2646  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;
       
     getnewblk (g, &newblk);     /* get a new block */      getnewblk (filedes, &newblk);       /* get a new block */
           
     if (*blknbr == ROOT) {              /* ROOT overflow is special */      if (*blknbr == ROOT) {              /* ROOT overflow is special */
   
Line 2846  static void splitp (global_handle *g, ch Line 2674  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;
                   
         gbl_write_block (g, ROOT, block0);          lseek (filedes, ROOT, 0);
           write (filedes, block0, BLOCKLEN);
                   
         /* shift trace_stack */          /* shift trace_stack */
         j = trx++;          j = trx++;
Line 2871  static void splitp (global_handle *g, ch Line 2700  static void splitp (global_handle *g, ch
         traceblk[1] = newblk;          traceblk[1] = newblk;
         *blknbr = newblk;          *blknbr = newblk;
                   
         getnewblk (g, &newblk); /* get a new block */          getnewblk (filedes, &newblk);   /* get a new block */
   
     }      }
   
Line 2913  static void splitp (global_handle *g, ch Line 2742  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 2925  static void splitp (global_handle *g, ch Line 2754  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;
   
         gbl_write_block (g, newblk, block0);          lseek (filedes, (long) (newblk) * (long) (BLOCKLEN), 0);
           write (filedes, block0, BLOCKLEN);
   
         (*offs) = limit;          (*offs) = limit;
                   
         insert (g, &block0[2], (long) UNSIGN (block0[0]), newblk);          insert (filedes, &block0[2], (long) UNSIGN (block0[0]), newblk);
                   
         /* up-date LL-PTR of RL-block */          /* up-date LL-PTR of RL-block */
         if (other != 0) {          if (other != 0) {
   
             gbl_read_block (g, other, block0);              lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
               read (filedes, 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;
               
             gbl_write_block (g, other, block0);              lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
               write (filedes, block0, BLOCKLEN);
   
         }          }
   
Line 2949  static void splitp (global_handle *g, ch Line 2781  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 2964  static void splitp (global_handle *g, ch Line 2796  static void splitp (global_handle *g, ch
   
         (*addr) -= limit;          (*addr) -= limit;
         (*offs) -= limit;          (*offs) -= limit;
   
         gbl_write_block (g, *blknbr, block);  
                   
           lseek (filedes, (long) (*blknbr) * (long) (BLOCKLEN), 0);
           write (filedes, block, BLOCKLEN);
         stcpy0 (block, block0, (long) BLOCKLEN);          stcpy0 (block, block0, (long) BLOCKLEN);
                   
         (*blknbr) = newblk;          (*blknbr) = newblk;
                   
         insert (g, &block0[2], (long) UNSIGN (block0[0]), newblk);          insert (filedes, &block0[2], (long) UNSIGN (block0[0]), newblk);
                   
         /* up-date LL-PTR of RL-block */          /* up-date LL-PTR of RL-block */
         if (other != 0) {          if (other != 0) {
   
             gbl_read_block (g, other, block0);              lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
               read (filedes, 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;
               
             gbl_write_block (g, other, block0);              lseek (filedes, (long) other * (long) (BLOCKLEN), 0);
               write (filedes, block0, BLOCKLEN);
   
         }          }
   
Line 2997  static void splitp (global_handle *g, ch Line 2831  static void splitp (global_handle *g, ch
  *  ins_key:    key to be inserted   *  ins_key:    key to be inserted
  *  keyl:       length of that key   *  keyl:       length of that key
  */   */
 static void update (global_handle *g, char *ins_key, long keyl)  static void update (short filedes, char *ins_key, long keyl)
 {  {
     long offset;      long offset;
     long addr;      long addr;
     unsigned long blknbr;      unsigned long blknbr;
     char block[BLOCKLEN];      char block[BLOCKLEN];
     long i, j, k;      long i, j, k;
       
     while (traceadr[trx] == 0) {        /* update of pointer blocks necessary */      while (traceadr[trx] == 0) {        /* update of pointer blocks necessary */
   
         if (--trx < 0) break;          if (--trx < 0) break;
                   
         blknbr = traceblk[trx];          blknbr = traceblk[trx];
         addr = traceadr[trx];          addr = traceadr[trx];
           
         gbl_read_block (g, blknbr, block);          lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
           read (filedes, block, BLOCKLEN);
                   
         {          {
             long    oldkeyl;              long    oldkeyl;
Line 3023  static void update (global_handle *g, ch Line 2858  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 3039  static void update (global_handle *g, ch Line 2874  static void update (global_handle *g, ch
             else if (j < 0) {           /* we need more space */              else if (j < 0) {           /* we need more space */
                           
                 /* block too small */                  /* block too small */
                 if ((offset - j) > DATALIM) splitp (g, block, &addr, &offset, &blknbr);                  if ((offset - j) > DATALIM) splitp (filedes, block, &addr, &offset, &blknbr);
                                   
                 i = offset;                  i = offset;
                 offset -= j;                  offset -= j;
Line 3062  static void update (global_handle *g, ch Line 2897  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 */
             gbl_write_block (g, blknbr, block);              lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
         }              write (filedes, block, BLOCKLEN);
   
         gbl_read_block (g, blknbr, block);          }
           
           lseek (filedes, (long) blknbr * (long) (BLOCKLEN), 0);
           read (filedes, block, BLOCKLEN);
   
     }      }
   
Line 3080  static void update (global_handle *g, ch Line 2918  static void update (global_handle *g, ch
  *  key_len:    length of that key   *  key_len:    length of that key
  *  blknbr:     key points to this block   *  blknbr:     key points to this block
  */   */
 static void insert (global_handle *g, char *ins_key, long key_len, unsigned long blknbr)        /* insert pointer */  static void insert (int filedes, char *ins_key, long key_len, unsigned long blknbr)     /* insert pointer */
 {  {
     unsigned long blk;      unsigned long blk;
     char block[BLOCKLEN];      char block[BLOCKLEN];
Line 3089  static void insert (global_handle *g, ch Line 2927  static void insert (global_handle *g, ch
     long needed;      long needed;
     long addr;      long addr;
     register int i, k;      register int i, k;
       
     trxsav = trx--;      trxsav = trx--;
     blk = traceblk[trx];      blk = traceblk[trx];
     addr = traceadr[trx];      addr = traceadr[trx];
   
     gbl_read_block (g, blk, block);      lseek (filedes, (long) (blk) * (long) (BLOCKLEN), 0);
       read (filedes, 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 3106  static void insert (global_handle *g, ch Line 2945  static void insert (global_handle *g, ch
   
     needed = key_len + 2 + PLEN;      needed = key_len + 2 + PLEN;
           
     if ((offset + needed) > DATALIM) splitp (g, block, &addr, &offset, &blk);      if ((offset + needed) > DATALIM) splitp (filedes, block, &addr, &offset, &blk);
           
     /*  insert key */      /*  insert key */
     i = (offset += needed);      i = (offset += needed);
Line 3130  static void insert (global_handle *g, ch Line 2969  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;
   
     gbl_write_block (g, blk, block);      lseek (filedes, (long) (blk) * (long) (BLOCKLEN), 0);
       write (filedes, block, BLOCKLEN);
           
     trx = trxsav;      trx = trxsav;
           
Line 3142  static void insert (global_handle *g, ch Line 2982  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 (global_handle *g, unsigned long blknbr)  static void b_free (short filedes, 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;
       
     /* mark block as empty */      /* mark block as empty */
     gbl_read_block (g, blknbr, block0);      lseek (filedes, (long) (blknbr) * BLOCKLEN, 0);
           read (filedes, block0, BLOCKLEN);
     block0[BTYP] = EMPTY;  
   
     gbl_write_block (g, blknbr, block0);      block0[BTYP] = EMPTY;
       
       lseek (filedes, (long) (blknbr) * BLOCKLEN, 0);
       write (filedes, block0, BLOCKLEN);
   
     /* do we have a list of free blocks? */      /* do we have a list of free blocks? */
     gbl_read_block (g, ROOT, block0);      lseek (filedes, ROOT, 0);
       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 (;;) {
           
             gbl_read_block (g, free, block0);              lseek (filedes, (long) free * (long) BLOCKLEN, 0);
               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 3184  static void b_free (global_handle *g, un Line 3028  static void b_free (global_handle *g, un
             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 3195  static void b_free (global_handle *g, un Line 3039  static void b_free (global_handle *g, un
             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;
               
             gbl_write_block (g, free, block0);              lseek (filedes, (long) free * (long) BLOCKLEN, 0);
               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 3212  static void b_free (global_handle *g, un Line 3057  static void b_free (global_handle *g, un
   
     }       } 
     else {      else {
         getnewblk (g, &free);  
           getnewblk (filedes, &free);
   
         /* set FBLK free blocks pointer */          /* set FBLK free blocks pointer */
         gbl_read_block (g, ROOT, block0);          lseek (filedes, ROOT, 0);
           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;
           
         gbl_write_block (g, ROOT, block0);          lseek (filedes, ROOT, 0);
           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 3236  static void b_free (global_handle *g, un Line 3084  static void b_free (global_handle *g, un
     block0[OFFS] = offset / 256;      block0[OFFS] = offset / 256;
     block0[OFFS + 1] = offset % 256;      block0[OFFS + 1] = offset % 256;
   
     gbl_write_block (g, free, block0);      lseek (filedes, (long) free * (long) BLOCKLEN, 0);
       write (filedes, block0, BLOCKLEN);
           
     return;      return;
 }                                       /* end of b_free() */  }                                       /* end of b_free() */
Line 3309  static void scandblk (char *block, long Line 3158  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 3356  static void scandblk (char *block, long Line 3205  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 (global_handle *g, unsigned long *blknbr)  static void getnewblk (int filedes, 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;
   
     gbl_read_block (g, ROOT, nblock);      lseek (filedes, ROOT, 0);
       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) {
           
         gbl_read_block (g, freeblks, nblock);          lseek (filedes, (long) (freeblks) * BLOCKLEN, 0);
           read (filedes, nblock, BLOCKLEN);
                   
         offset = UNSIGN (nblock[OFFS]) * 256 + UNSIGN (nblock[OFFS + 1]);          offset = UNSIGN (nblock[OFFS]) * 256 + UNSIGN (nblock[OFFS + 1]);
   
Line 3382  static void getnewblk (global_handle *g, Line 3233  static void getnewblk (global_handle *g,
             /* update RL-block, if any */              /* update RL-block, if any */
             if (other) {              if (other) {
   
                 gbl_read_block (g, other, nblock);                  lseek (filedes, (long) (other) * BLOCKLEN, 0);
                   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;
                   
                 gbl_write_block (g, other, nblock);                  lseek (filedes, (long) (other) * BLOCKLEN, 0);
                   write (filedes, nblock, BLOCKLEN);
   
             }              }
   
             /* update ROOT block */              /* update ROOT block */
             gbl_read_block (g, ROOT, nblock);              lseek (filedes, ROOT, 0);
               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;
               
             gbl_write_block (g, ROOT, nblock);              lseek (filedes, ROOT, 0);
               write (filedes, nblock, BLOCKLEN);
                           
             return;              return;
   
Line 3411  static void getnewblk (global_handle *g, Line 3266  static void getnewblk (global_handle *g,
         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;
           
         gbl_write_block (g, freeblks, nblock);          lseek (filedes, (long) (freeblks) * BLOCKLEN, 0);
           write (filedes, nblock, BLOCKLEN);
                   
         return;          return;
   
Line 3423  static void getnewblk (global_handle *g, Line 3279  static void getnewblk (global_handle *g,
     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;
       
     gbl_write_block (g, ROOT, nblock);      lseek (filedes, ROOT, 0);
       write (filedes, nblock, BLOCKLEN);
           
     *blknbr = no_of_blks;      *blknbr = no_of_blks;
       
       for (;;) {
   
     gbl_write_block (g, no_of_blks, nblock);          errno = 0;
           
           lseek (filedes, (long) (no_of_blks) * BLOCKLEN, 0);
           write (filedes, nblock, BLOCKLEN);
           
           if (errno == 0) break;
   
           panic ();
   
       }
   
     return;      return;
   
Line 3557  static short int g_collate (char *t) Line 3425  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 3599  short g_numeric (char *str) Line 3468  short g_numeric (char *str)
   
 }                                       /* end g_numeric() */  }                                       /* end g_numeric() */
   
   
 /* DEPRECATED: use gbl_close_all() instead */  
 void close_all_globals (void)  void close_all_globals (void)
 {                                         {                                       
     gbl_close_all ();      register int i;
       
       for (i = 0; i < NO_GLOBLS; i++) {
           
           if (oldfil[i][0] != NUL) {
               
               close (olddes[i]);
               
               usage[i] = 0;
               olddes[i] = 0;
               oldfil[i][0] = NUL;
   
           }
   
       }
   
     return;      return;
   
 }                                       /* end close_all_globals() */  }                                       /* end close_all_globals() */
   
 static void panic (void)  static void panic (void)
 {  {                                       
     printf ("write failed\r\n");  
       
     printf ("\033[s\033[25H\033[5;7mwrite needs more disk space immediately\007");      printf ("\033[s\033[25H\033[5;7mwrite needs more disk space immediately\007");
     sleep (1);      sleep (1);
     printf ("\033[m\007\033[2K\033[u");      printf ("\033[m\007\033[2K\033[u");
Line 3631  static void panic (void) Line 3511  static void panic (void)
   
 void gbl_dump_stat(void)  void gbl_dump_stat(void)
 {  {
     global_handle *g;      register int i;
     int ct;      
     int miss_pct;      printf ("FreeM Global Statistics [PID %d]\r\n", pid);
     int hit_pct;  
     unsigned long access_total;         printf ("%-10s%-20s%s\r\n", "USECT", "AGE", "FILE");
     unsigned long hit_total;      printf ("%-10s%-20s%s\r\n", "=====", "===", "====");
     unsigned long mem_reads_total;      
       for (i = 0; i < NO_GLOBLS; i++) {
     mem_reads_total = 0;          printf ("%-10d%-20ld%s\r\n", usage[i], g_ages[i], oldfil[i]);    
     printf ("\r\nFreeM Global Statistics [PID %d]\r\n\r\n", pid);      }
   
     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%-10s%-10s%-10s%-12s%-20s%-10s%s\r\n", "======", "=====", "=====", "======", "========", "==========", "===", "========", "====");  
   
     access_total = 0;  
     ct = 0;  
     for (g = global_handles_head; g != NULL; g = g->next) {  
         printf ("%-20s%-10ld%-10ld%-10ld%-10ld%-12ld%-20ld%-10ld%s\r\n",  
                 g->global_name,  
                 g->use_count,  
                 g->read_ops,  
                 g->write_ops,  
                 g->memory_reads,  
                 g->cache_misses,  
                 g->age,  
                 g->last_block,  
                 g->global_path);  
         ct++;  
         mem_reads_total += g->memory_reads;  
         access_total += g->use_count;        
     }  
     if (!ct) printf ("<no globals opened in this pid>\r\n");  
   
     hit_total = access_total - gbl_cache_misses;  
     miss_pct = (gbl_cache_misses * 100) / access_total;  
     hit_pct = (hit_total * 100) / 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 misses:    %ld\t(%d%%)\r\n", gbl_cache_misses, miss_pct);  
     printf ("Disk reads avoided:  %ld\r\n", mem_reads_total);  
           
 }  }

Removed from v.1.22  
changed lines
  Added in v.1.24


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>