"Fossies" - the Fresh Open Source Software Archive

Member "libdbh2-5.0.22/src/dbh_static.i" (22 Sep 2016, 62886 Bytes) of package /linux/misc/libdbh2-5.0.22.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) ALAN Interactive Fiction Language source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "dbh_static.i": 5.0.21_vs_5.0.22.

    1 #ifdef COPYRIGHT_INFORMATION
    2 #include "gplv3.h"
    3 #endif
    4 /*
    5  * Copyright (C) 2002-2016 Edscott Wilson Garcia
    6  * EMail: edscott@imp.mx
    7  *
    8  *
    9  * This program is free software; you can redistribute it and/or modify
   10  * it under the terms of the GNU General Public License as published by
   11  * the Free Software Foundation; either version 3 of the License, or
   12  * (at your option) any later version.
   13  *
   14  * This program is distributed in the hope that it will be useful,
   15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17  * GNU General Public License for more details.
   18  *
   19  * You should have received a copy of the GNU General Public License
   20  * along with this program; if not, write to the Free Software
   21  * Foundation.
   22  */
   23 
   24 // This file contains definitions of static functions
   25 // No exported functions or symbols should be in this file.
   26 
   27 
   28 static int open_timeout = 0;
   29 static pthread_mutex_t new_mutex = PTHREAD_MUTEX_INITIALIZER;
   30 
   31 static int sdbh_writeheader (DBHashTable * dbh, int flush);
   32 static int sdbh_updateBranch (DBHashTable *, FILE_POINTER);
   33 static unsigned char sdbh_readBranches (DBHashTable *, FILE_POINTER);
   34 
   35 static FILE_POINTER *sdbh_locate (DBHashTable *, FILE_POINTER *);
   36 static FILE_POINTER *sdbh_locateTop (DBHashTable *, FILE_POINTER *, int);
   37 static FILE_POINTER *sdbh_locateFind (DBHashTable *, FILE_POINTER *, int);
   38 static void sdbh_cuenta (unsigned char *, unsigned char, FILE_POINTER);
   39 static FILE_POINTER sdbh_write (char, DBHashTable *, unsigned char);
   40 static int sdbh_read (char, DBHashTable *, unsigned char);
   41 static int sdbh_readheader (DBHashTable *);
   42 
   43 #ifdef TURN
   44 static FILE_POINTER sdbh_turnaround (FILE_POINTER);
   45 #endif
   46 static FILE_POINTER sdbh_z (unsigned char, unsigned char);
   47 static unsigned char sdbh_cuantumR (FILE_POINTER, unsigned char, FILE_POINTER *);
   48 static unsigned char sdbh_cuantum (FILE_POINTER, unsigned char, FILE_POINTER *);
   49 static void sdbh_cifra (unsigned char *, unsigned char, unsigned char, FILE_POINTER *);
   50 
   51 static int sdbh_reversebarre (DBHashTable *, FILE_POINTER, int);
   52 static int sdbh_barre (DBHashTable *, FILE_POINTER, int);
   53 
   54 static void sdbh_transfer (DBHashTable *);
   55 static DBHashTable *sdbh_open_S (const char *, int, int);
   56 
   57 static int sdbh_size (DBHashTable *, FILE_POINTER);
   58 
   59 #ifdef PARALLEL_SAFE
   60 static char *lock_name(const char *archivo);
   61 #endif
   62 
   63 /*************************************************************************/
   64 static int my_open(const char *filename, int flags){
   65 #ifndef HAVE_WINDOWS_H
   66     if (flags & O_CREAT) return open(filename, flags, 0640);
   67     return open(filename, flags);
   68 #else
   69     if (flags & O_CREAT) return open(filename, flags|_O_BINARY, 0640);
   70     return open(filename, flags|_O_BINARY);
   71 #endif
   72 }
   73 
   74 #if 0
   75 // Faster without this.
   76 static int
   77 sync_fd (int fd) {
   78     /*if (fsync(fd) < 0) {
   79        // this should not happen, really.
   80        ERR("fsync(): %s\n", strerror(errno));
   81        return 0;
   82        } */
   83     return 1;
   84 }
   85 #endif
   86 
   87 static int
   88 advance_fp (DBHashTable * dbh, FILE_POINTER offset) {
   89     //if (!sync_fd(dbh->fd)) return 0;
   90     if(lseek (dbh->fd, (off_t) offset, SEEK_CUR) < 0) {
   91         errno = EBADF;
   92         ERR( "Error: advance_fp failed to advance fp %lld\n", (long long)offset);
   93         return 0;
   94     }
   95     return 1;
   96 }
   97 
   98 static int
   99 place_fp_at (DBHashTable * dbh, off_t seek) {
  100     //if (!sync_fd(dbh->fd)) return 0;
  101     if(lseek (dbh->fd, (off_t) seek, SEEK_SET) != seek) {
  102         // this should not happen...
  103         errno = EBADF;
  104     ERR( "Error: sdbh_locate() cannot place file pointer at bof=0x%llu\n", (long long unsigned)seek);
  105         return 0;
  106     }
  107     return 1;
  108 }
  109 
  110 static FILE_POINTER
  111 place_eof (DBHashTable * dbh) {
  112     //if (!sync_fd(dbh->fd)) return 0;
  113     FILE_POINTER eof;
  114     eof = (FILE_POINTER) lseek (dbh->fd, (off_t) 0L, SEEK_END);
  115     if(eof < sizeof (dbh_header_t)) {
  116         errno = EBADF;
  117         ERR( "Error: tell_eof() <  sizeof (dbh_header_t)\n");
  118         eof = -1;
  119     }
  120     if(eof < 0) {
  121         // this should not happen...
  122         errno = EBADF;
  123         ERR( "Error: tell_eof() cannot place file pointer at eof\n");
  124     }
  125     return eof;
  126 }
  127 
  128   /* Funciones nivel 0: */
  129 static void
  130 sdbh_operate (DBHashTable * dbh) {
  131     if(dbh == NULL) {
  132         ERR ("Must define function operate(place*) before doing a sweep\n");
  133     }
  134 }
  135 
  136 static char *
  137 sdbh_randomfilename (DBHashTable * dbh, char code) {
  138     time_t segundos;
  139     FILE_POINTER divisor;
  140     char *archivo;
  141     const char *tmpdir;
  142     if(!dbh) return NULL;
  143     // determine best tmp directory
  144     if(dbh->head_info->user_tmpdir == 0) {
  145         struct stat dbh_st, tmp_st;
  146         if (stat (dbh->path, &dbh_st) < 0){
  147             ERR("Unable to stat: %s\n", dbh->path);
  148             return NULL;
  149         }
  150 #ifdef HAVE_WINDOWS_H
  151         const char * tmp = getenv("TEMP");
  152     if (!tmp || access(tmp,W_OK) < 0) tmp ="c:\\";
  153 #else
  154         const char *tmp = "/tmp";
  155 #endif
  156 
  157         if (stat (tmp, &tmp_st) < 0){
  158             ERR("Unable to stat: %s\n", tmp);
  159             return NULL;
  160         }
  161     if (dbh->tmpdir) {
  162                 free(dbh->tmpdir);
  163         }
  164         dbh->tmpdir = NULL;
  165         // Make sure tmp dir is on same device.
  166         DBG("system temp dir is %s \n", tmp);
  167         if(dbh_st.st_dev == tmp_st.st_dev) {
  168             dbh->tmpdir = (char *)malloc (strlen (tmp) + 1);
  169         if (dbh->tmpdir == NULL) {
  170          ERR( "malloc dbh->tmpdir: %s\n", strerror(errno));
  171                  return NULL;
  172         }   
  173         strcpy (dbh->tmpdir, tmp);
  174         } else {
  175             // system tmp dir is not on the same device.    
  176 #ifdef HAVE_WINDOWS_H 
  177             dbh->tmpdir = (char *)malloc (strlen (tmp) + 1);
  178         strcpy (dbh->tmpdir, tmp);
  179 #else
  180             if (*(dbh->path) =='/') {
  181                 dbh->tmpdir = (char *)malloc (strlen (dbh->path) + 1);
  182             if (dbh->tmpdir == NULL) {
  183            ERR( "malloc dbh->tmpdir: %s\n", strerror(errno));
  184                    return NULL;
  185                 }
  186             strcpy (dbh->tmpdir, dbh->path);
  187                 *(strrchr(dbh->tmpdir, '/')) = 0;
  188             } else {
  189                 dbh->tmpdir = (char *)malloc (1024);
  190             if (dbh->tmpdir == NULL) {
  191            ERR( "malloc dbh->tmpdir: %s\n", strerror(errno));
  192                    return NULL;
  193                 }
  194                 if (!getcwd(dbh->tmpdir, 1024)){
  195            ERR( "!getcwd: %s\n", strerror(errno));
  196                    return NULL;
  197                 }
  198             }
  199 #endif
  200         }
  201     }
  202     tmpdir = dbh->tmpdir;
  203  
  204     time (&segundos);
  205     int try=0;
  206 retry:
  207     srand ((unsigned)segundos);
  208     divisor = RAND_MAX / 10000;
  209     // Usage of rand is not security related. Just to get a random temporary file name.
  210     // coverity[dont_call : FALSE]
  211     if((segundos = rand () / divisor) > 100000L)
  212         segundos = 50001;
  213     archivo = (char *)malloc (strlen (tmpdir) + 1 + 1 + 6 + 4 + 1);
  214     if (archivo == NULL) {
  215      ERR( "malloc filename: %s\n", strerror(errno));
  216          return NULL;
  217     } 
  218 #ifdef HAVE_WINDOWS_H 
  219     sprintf (archivo, "%s%c%c%ld.tmp", tmpdir, '\\', code, (long)segundos);
  220 #else
  221     sprintf (archivo, "%s/%c%ld.tmp", tmpdir, code, (long)segundos);
  222 #endif
  223 
  224     // if the file exists (fat chance), retry with a different random number...
  225     struct stat st;
  226     if (stat(archivo, &st)==0){
  227     if (segundos > 0) segundos--;
  228     else segundos++;
  229     if (try++ < 3) {
  230         free(archivo);
  231             goto retry;
  232         }
  233     free(archivo);
  234     return NULL;
  235     }
  236 
  237     return archivo;
  238 }  /*******************************************************************************/
  239 
  240 #if 0
  241 this is unreliable in Linux...
  242 //mode=1 --> write lock
  243 static void
  244 lock_fd (int fd, int mode, const char *archivo) {
  245     //  return;
  246     // get the file lock, wait if necesary:
  247     struct flock lock;
  248 
  249     lock.l_whence = SEEK_SET;
  250     lock.l_start = 0;
  251     lock.l_len = 0;             // to eof  
  252 
  253     if(mode) {
  254         lock.l_type = F_WRLCK;
  255     } else {
  256         lock.l_type = F_RDLCK;
  257     }
  258 
  259     int try=0;
  260 retry:
  261     if(fcntl (fd, F_SETLKW, &lock) < 0) {
  262     if (try++ < 3) {
  263         sleep(1);
  264         goto retry;
  265     }
  266         DBG( "fcntl(F_SETLKW)(%s): %s\n", archivo, strerror (errno));
  267     }
  268 }
  269 
  270 static void
  271 unlock (int fd) {
  272 
  273 
  274     // release the lock:
  275     struct flock lock;
  276 
  277     lock.l_whence = SEEK_SET;
  278     lock.l_start = 0;
  279     lock.l_len = 0;             // to eof  
  280 
  281     lock.l_type = F_UNLCK;
  282     int try=0;
  283 retry:
  284     if(fcntl (fd, F_SETLKW, &lock) < 0) {
  285     if (try++ < 3) {
  286         sleep(1);
  287         goto retry;
  288     }
  289         DBG( "fcntl(F_SETLKW): %s\n", strerror (errno));
  290     }
  291 }
  292 #endif
  293 
  294 
  295   /* Functions: ************************************************************** */
  296 static unsigned char
  297 sdbh_readBranches (DBHashTable * dbh, FILE_POINTER seek) {
  298     FILE_POINTER *rama;
  299     unsigned char ramas;
  300     rama = dbh->newbranch;
  301     TRACE ("sdbh_readBranches\n");
  302 
  303     if(!place_fp_at (dbh, (off_t)seek)){
  304         return 0;
  305     }
  306     if(read (dbh->fd, &ramas, 1) != 1) {
  307         ERR ("sdbh_readBranches error 3.1\n");
  308         return 0;
  309     }
  310     if (ramas > dbh->head_info->n_limit){
  311         ERR ("Corrupted loop boundary \"ramas\"\n");
  312         return 0;
  313     }
  314     DBG ("sdbh_readBranches ramas=%lld\n", (long long)ramas);
  315     if(!advance_fp (dbh, 1L + sizeof (FILE_POINTER))) {
  316         return 0;
  317     }
  318 
  319     if(read (dbh->fd, rama, sizeof (FILE_POINTER) * ramas) != sizeof (FILE_POINTER) * ramas) {
  320         ERR ("sdbh_readBranches error 3.2\n");
  321         return 0;
  322     }
  323     DBG ("read:");
  324     int i;
  325     for(i = 0; i < ramas; i++){
  326         DBG (" rama[%d]=0x%llu\n", i, (long long unsigned)(rama[i]));
  327     }
  328 #ifdef TURN
  329     {
  330         int i;
  331         for(i = 0; i < ramas; i++)
  332             rama[i] = sdbh_turnaround (rama[i]);
  333     }
  334 #endif
  335     return ramas;
  336 } /***************************************************/
  337 
  338 static int
  339 sdbh_updateBranch (DBHashTable * dbh, FILE_POINTER seek) {
  340     TRACE ("sdbh_updateBranch\n");
  341     FILE_POINTER *rama;
  342     unsigned char ramas;
  343     rama = dbh->newbranch;
  344     if(!place_fp_at (dbh, (off_t)seek)) {
  345         return 0;
  346     }
  347     if(read (dbh->fd, &ramas, 1) != 1) {
  348         ERR ("sdbh_updateBranch read error 4.1\n");
  349         return 0;
  350     }
  351 
  352     if(!advance_fp (dbh, 1L + sizeof (FILE_POINTER))){
  353         return 0;
  354     }
  355 
  356 #ifdef TURN
  357     {
  358         int i;
  359         for(i = 0; i < ramas; i++)
  360             rama[i] = sdbh_turnaround (rama[i]);
  361     }
  362 #endif
  363     DBG ("Updating branch information for new record:");
  364     int i;
  365     if (ramas > dbh->head_info->n_limit){
  366         ERR ("Corrupted loop boundary \"ramas\"\n");
  367         return 0;
  368     }
  369     for(i = 0; i < ramas; i++){
  370         DBG (" rama[%d]=0x%llu\n", i, (long long unsigned)(rama[i]));
  371     }
  372 
  373     if(write (dbh->fd, rama, sizeof (FILE_POINTER) * ramas) != sizeof (FILE_POINTER) * ramas) {
  374         ERR ("sdbh_updateBranch write error 4.2\n");
  375         return 0;
  376     }
  377 #ifdef TURN
  378     {
  379         int i;
  380         for(i = 0; i < ramas; i++)
  381             rama[i] = sdbh_turnaround (rama[i]);
  382     }
  383 #endif
  384     return 1;
  385 }  /*****************************************************/
  386 
  387 #define BRANCHOFF (dbh->head_info->n_limit-dbh->newbranches)
  388 #define CURRENTSEEK fp[0]
  389 #define LASTSEEK fp[1]
  390 #define CURR_BRANCH fp[2]
  391 #define SWITCHED (dbh->head_info->reservedD)
  392 //FILE_POINTER *fp must have size = 3
  393 static FILE_POINTER *
  394 sdbh_locate (DBHashTable * dbh, FILE_POINTER * fp) {
  395     TRACE ("sdbh_locate\n");
  396     FILE_POINTER currentseek,
  397       lastseek;
  398     int i;                      /*,offset; */
  399     lastseek = currentseek = 0;
  400     CURRENTSEEK = LASTSEEK = CURR_BRANCH = 0;   /* ERROR value assigned */
  401     currentseek = dbh->head_info->bof;
  402 
  403     if(!place_fp_at (dbh, (off_t)currentseek)) {
  404         return NULL;
  405     }
  406 
  407     if(!sdbh_read (NEW, dbh, 1)) {
  408         return fp;
  409     }
  410   loop:
  411 #define OFFSET (i+(dbh->head_info->n_limit-dbh->newbranches))
  412     for(i = 0; i < dbh->newbranches; i++) {
  413         if(*(dbh->key + OFFSET) != *(dbh->newkey + OFFSET))
  414         {
  415             lastseek = currentseek;
  416             if((currentseek = *(dbh->newbranch + i)) == 0) {
  417                 CURR_BRANCH = i;
  418                 break;
  419             }
  420             if(!place_fp_at (dbh, (off_t)currentseek)) {
  421                 return NULL;
  422             }
  423             if(!sdbh_read (NEW, dbh, 1)) {
  424                 return fp;
  425             }
  426             goto loop;
  427         }
  428     }
  429     CURRENTSEEK = currentseek;
  430     LASTSEEK = lastseek;
  431     return fp;
  432 }
  433 
  434 static FILE_POINTER *
  435 sdbh_locateTop (DBHashTable * dbh, FILE_POINTER * fp, int key_length) {
  436     TRACE ("sdbh_locateFind\n");
  437     FILE_POINTER currentseek,
  438       lastseek;
  439     int i;
  440     lastseek = currentseek = 0;
  441     CURRENTSEEK = LASTSEEK = CURR_BRANCH = 0;   /* ERROR value assigned */
  442     currentseek = dbh->head_info->bof;
  443 
  444     if(!place_fp_at (dbh, (off_t)currentseek)) {
  445         return NULL;
  446     }
  447 
  448     if(!sdbh_read (NEW, dbh, 1)) {
  449         return fp;
  450     }
  451     if (key_length > dbh->newbranches) key_length = dbh->newbranches;
  452 //        fprintf(stderr, "*branch %d: newkey=%s branches=%d\n", 0, dbh->newkey, dbh->newbranches);
  453 //        fprintf(stderr, "looking for %s ...\n", dbh->key);
  454     
  455     FILE_POINTER addr[key_length];
  456     memcpy(addr, dbh->newbranch, key_length*sizeof(FILE_POINTER));
  457     if (memcmp((void *)(dbh->key), (void *)(dbh->newkey), key_length) == 0){
  458         CURRENTSEEK = currentseek;
  459         return fp;
  460     }
  461 
  462     int j=0;
  463 loop:
  464     for (i=0; i<key_length; i++){
  465 //        fprintf(stderr, "%d) %c ?= %c\n", j, *(dbh->key + j),*(dbh->newkey + OFFSET));
  466         if (*(dbh->key + j) != *(dbh->newkey + OFFSET)){
  467             if (!dbh->newbranch[i]) return NULL; // no next node
  468             // otherwise, read next node:
  469 //            fprintf(stderr, "next branch %d: (addr:%p)\n", i, dbh->newbranch[i]);
  470             lastseek = currentseek;
  471             currentseek = dbh->newbranch[i];
  472             if(!place_fp_at (dbh, (off_t)currentseek)) {
  473                 return NULL;
  474             }
  475             if(!sdbh_read (NEW, dbh, 1)) {
  476                 return NULL;
  477             }
  478             if (memcmp((void *)(dbh->key), (void *)(dbh->newkey), key_length) == 0) {
  479                 //fprintf(stderr, "branch %d: (addr:%p) newkey=%s newbranches=%d\n", i,  dbh->newbranch[i], dbh->newkey, dbh->newbranches);
  480                 CURRENTSEEK = currentseek;
  481                 //fprintf(stderr, "fp: %p %p %p\n", fp[0], fp[1], fp[2]);
  482                 return fp;
  483             }
  484             goto loop;
  485         }
  486         j++;
  487     }
  488     return NULL;
  489 }
  490 
  491 static FILE_POINTER *
  492 sdbh_locateFind (DBHashTable * dbh, FILE_POINTER * fp, int keys) {
  493     TRACE ("sdbh_locateFind\n");
  494     FILE_POINTER currentseek,
  495       lastseek;
  496     int i;
  497     lastseek = currentseek = 0;
  498     CURRENTSEEK = LASTSEEK = CURR_BRANCH = 0;   /* ERROR value assigned */
  499     currentseek = dbh->head_info->bof;
  500 
  501     if(!place_fp_at (dbh, (off_t)currentseek)) {
  502         return NULL;
  503     }
  504 
  505     if(!sdbh_read (NEW, dbh, 1)) {
  506         return fp;
  507     }
  508     if(keys > dbh->head_info->n_limit)
  509         keys = dbh->head_info->n_limit;
  510   loop:
  511     for(i = 0; i < dbh->newbranches - (dbh->head_info->n_limit - keys); i++) {
  512         /*  offset=i+(dbh->head_info->n_limit-dbh->newbranches); */
  513         if(*(dbh->key + OFFSET) != *(dbh->newkey + OFFSET)) {
  514             lastseek = currentseek;
  515             if((currentseek = *(dbh->newbranch + i)) == 0) {
  516                 CURR_BRANCH = i;
  517                 break;
  518             }
  519             if(!place_fp_at (dbh, (off_t)currentseek)) {
  520                 return NULL;
  521             }
  522             if(!sdbh_read (NEW, dbh, 1)) {
  523                 return fp;
  524             }
  525             goto loop;
  526         }
  527     }
  528     CURRENTSEEK = currentseek;
  529     LASTSEEK = lastseek;
  530     return fp;
  531 }
  532 
  533 #ifdef PARALLEL_SAFE
  534 static char *lock_name(const char *archivo){
  535     if (!archivo || strlen(archivo)==0){
  536     ERR("Cannot determine lock name for %s\n", 
  537         (archivo)?archivo:"NULL");
  538     return NULL;
  539    }
  540 
  541     char *path;
  542 
  543 #ifdef HAVE_REALPATH
  544     path = realpath(archivo, NULL);
  545     if (!path) {
  546         ERR( "realpath(%s): %s\n", archivo, strerror(errno));
  547     }
  548 #else
  549     path = (char *)malloc(strlen(archivo)+1);
  550     if (path) strcpy(path, archivo);
  551 #endif
  552 
  553     if (!path){
  554         ERR( "1.malloc path %s: %s\n", path, strerror(errno));
  555         return NULL;
  556     }
  557 
  558  
  559     // Get inode information:
  560     struct stat st;
  561     if (stat(path, &st) < 0){
  562     // This is a valid return value. 
  563     NOOP("Cannot stat %s: %s\n", path, strerror(errno));
  564     free(path);
  565     return NULL;
  566     }
  567 
  568     // Build shm_name
  569     char buffer[1024];
  570     memset(buffer, 0, 1024);
  571     sprintf(buffer, "/%d-%d", (int)st.st_dev, (int)st.st_ino);
  572 
  573     char *shm_name = (char *)malloc((strlen(buffer)+1)*sizeof(char));
  574     if (!shm_name) {
  575     ERR("Cannot malloc lock name for %s\n", path);
  576     return NULL;
  577    }
  578     memset(shm_name, 0, strlen(buffer)+1);
  579     sprintf(shm_name, "%s", buffer);
  580     free(path);
  581     return shm_name;
  582 }
  583 
  584 static char *sem_name(const char *archivo){
  585     char *untagged_name = lock_name(archivo);
  586     if (!untagged_name) return NULL;
  587     char *name = (char *)malloc((strlen(untagged_name)+strlen("-ns")+1)*sizeof(char));
  588     if (!name){
  589         errno=ENOMEM;
  590         free(untagged_name);
  591         return NULL;
  592     }
  593     sprintf(name, "%s-ns", untagged_name);
  594     free(untagged_name);
  595     return name;
  596 }
  597 
  598 
  599 
  600 
  601 
  602 #endif
  603 
  604 static dbh_lock_t *
  605 open_shm_lock(const char *archivo){
  606 #ifndef PARALLEL_SAFE
  607     return NULL;
  608 #else
  609     char *shm_name=lock_name(archivo);
  610     if (!shm_name){
  611     // This would indicate something is wrong...
  612     ERR("Cannot get lock name for %s\n", 
  613         archivo);
  614     return NULL;
  615     }
  616 
  617     int fd = shm_open (shm_name, O_RDWR, S_IRUSR | S_IWUSR);
  618     if (fd > 0){
  619     NOOP("Lockfile exists %s -> %s\n", archivo, shm_name);
  620     } else {
  621     fd = shm_open (shm_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  622     }
  623     if(fd < 0) {
  624     ERR("Cannot open shared memory file descriptor for %s (%s): %s\n", 
  625         shm_name, archivo, strerror (errno));
  626     free(shm_name);
  627     return NULL;
  628     } else {
  629     if(ftruncate (fd, sizeof(dbh_lock_t)) < 0) {
  630         ERR("Cannot ftruncate shared memory item for %s: %s\n", 
  631             archivo, strerror (errno));
  632         free(shm_name);
  633         close(fd);
  634         return NULL;
  635     }
  636     }
  637     dbh_lock_t *lock_p = (dbh_lock_t *) mmap (NULL, sizeof(dbh_lock_t),
  638     PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  639     if (lock_p == MAP_FAILED){
  640     ERR("Cannot mmap shared memory item for %s: %s\n", 
  641         archivo, strerror (errno));
  642     close (fd);
  643     shm_unlink (shm_name);
  644         char *nsem_name = sem_name(archivo);
  645     if (nsem_name){
  646             sem_unlink (nsem_name);
  647             free(nsem_name);
  648         }
  649     free(shm_name);
  650     return NULL;
  651     } 
  652 
  653     
  654     free(shm_name);
  655     close (fd);
  656     return lock_p;
  657 #endif
  658 }
  659 
  660 static void
  661 destroy_shm_lock(char *archivo, dbh_lock_t *lock_p){
  662 #ifdef PARALLEL_SAFE
  663     if (!lock_p) return;
  664     char *shm_name=lock_name(archivo);
  665     if (!shm_name) {
  666     // Nothing to destroy.
  667     return;
  668     }
  669     munmap (lock_p, sizeof(dbh_lock_t));
  670     shm_unlink (shm_name);
  671     free(shm_name);
  672 #endif
  673 }
  674 
  675 static void
  676 clear_shm_lock(const char *archivo){
  677 #ifndef PARALLEL_SAFE
  678     return;
  679 #else
  680     char *shm_name=lock_name(archivo);
  681     if (!shm_name){
  682     // Nothing to clear.
  683     return;
  684     }
  685     // open it.
  686     dbh_lock_t *lock_p = open_shm_lock(archivo);
  687     // clear it.
  688 
  689     lock_p->write_lock_count = 0;
  690     lock_p->write_lock = 0;
  691     lock_p->read_lock_count = 0;
  692     
  693     if(msync (lock_p,  sizeof(dbh_lock_t), MS_ASYNC) < 0){
  694             ERR("(1) Cannot msync shared memory item for %s: %s\n", 
  695                 archivo, strerror (errno));
  696     }
  697         
  698     munmap (lock_p, sizeof(dbh_lock_t));
  699     // erase it (if not open elsewhere)
  700     shm_unlink (shm_name);
  701     free(shm_name);
  702     char *nsem_name = sem_name(archivo);
  703     if (nsem_name){
  704         sem_unlink(nsem_name);
  705         free(nsem_name);
  706     }
  707     return;
  708 #endif
  709 }
  710 
  711 
  712 static DBHashTable * 
  713 sdbh_create (const char *path, unsigned char key_length, int flags) {
  714     DBHashTable *dbh;
  715     if (key_length > 254){
  716         ERR("sdbh_create(%s): key_length is limited to 254 bytes...\n", path);
  717         return NULL;
  718     }
  719     dbh = (DBHashTable *) malloc (sizeof (DBHashTable));
  720     if(dbh == NULL){
  721     ERR( "malloc(%ld): %s\n", (long)sizeof (DBHashTable), strerror(errno));
  722     return NULL;
  723     }
  724     memset (dbh, 0, sizeof (DBHashTable));
  725     dbh->lock_attempt_limit = open_timeout;
  726     /////////////////////////////////////////////
  727     
  728     unlink (path);
  729     dbh->fd = my_open (path, O_CREAT | O_RDWR | O_TRUNC);
  730     if(dbh->fd < 0) {
  731         free (dbh);
  732         ERR("sdbh_create(%s): %s\n", path, strerror (errno));
  733         return NULL;
  734     }
  735 
  736     dbh->head_info = (dbh_header_t *) malloc (sizeof (dbh_header_t));
  737      if (dbh->head_info == NULL) {
  738         free (dbh);
  739     ERR( "malloc(%ld): %s\n", (long)sizeof (dbh_header_t), strerror(errno));
  740         return NULL;
  741      }  
  742      
  743     memset ((void *)(dbh->head_info), 0, sizeof (dbh_header_t));
  744 #ifdef PARALLEL_SAFE
  745     if (flags & DBH_PARALLEL_SAFE){
  746         char *nsem_name = sem_name(path);
  747         if (!nsem_name) {
  748         ERR( "malloc(%ld): %s\n", (long)strlen(path), strerror(errno));
  749             free (dbh);
  750             return NULL;
  751         }
  752         dbh->sem = sem_open(nsem_name, O_CREAT, 0700, 1);
  753         free(nsem_name);
  754 
  755         clear_shm_lock(path);
  756         dbh->lock_p = open_shm_lock(path);
  757     }
  758 #endif
  759 
  760     dbh->head_info->bof = sizeof (dbh_header_t);
  761     dbh->head_info->n_limit = key_length;
  762     dbh->head_info->user_tmpdir = 0;
  763     dbh->head_info->sweep_erased = 0;
  764     dbh->head_info->total_space = dbh->head_info->data_space = dbh->head_info->erased_space = 0;
  765     strncpy (dbh->head_info->version, DBH_FILE_VERSION, 15);
  766     dbh->head_info->records = 0;
  767     dbh->operate = sdbh_operate;
  768     dbh->branch = (FILE_POINTER *) malloc (dbh->head_info->n_limit * sizeof (FILE_POINTER));
  769      if (dbh->branch == NULL) {
  770      ERR( "malloc dbh->branch: %s\n", strerror(errno));
  771          dbh_close(dbh);
  772         return NULL;
  773      }      
  774      dbh->newbranch = (FILE_POINTER *) malloc (dbh->head_info->n_limit * sizeof (FILE_POINTER));
  775       if (dbh->newbranch == NULL) {
  776      ERR( "malloc dbh->newbranch: %s\n", strerror(errno));
  777          dbh_close(dbh);
  778         return NULL;
  779      }        
  780      dbh->key = (unsigned char *)malloc (key_length);
  781      if (dbh->key == NULL) {
  782      ERR( "malloc dbh->key: %s\n", strerror(errno));
  783          dbh_close(dbh);
  784         return NULL;
  785      }  
  786      dbh->newkey = (unsigned char *)malloc (key_length);
  787      if (dbh->newkey == NULL) {
  788      ERR( "malloc dbh->newkey: %s\n", strerror(errno));
  789          dbh_close(dbh);
  790         return NULL;
  791      }          
  792      dbh->path = (char *)malloc (strlen (path) + 1);
  793      if (dbh->path == NULL || dbh->newbranch == NULL ||
  794         dbh->key == NULL || dbh->newkey == NULL || dbh->path == NULL) {
  795      ERR( "malloc dbh->path: %s\n", strerror(errno));
  796          dbh_close(dbh);
  797         return NULL;
  798      }  
  799 
  800     strcpy (dbh->path, path);
  801 
  802     dbh->head_info->record_length = 0;
  803     dbh->head_info->writeOK = 1;
  804     sdbh_size (dbh, DEFAULT_DBH_DATASIZE);
  805     dbh->bytes_userdata = 0;
  806 
  807     sdbh_writeheader (dbh, 1);
  808     DBG (" created %s \n", path);
  809     return dbh;
  810 }
  811 
  812 static DBHashTable *
  813 sdbh_open_S (const char *archivo, int mode, int flags) {
  814     TRACE ("sdbh_open_S: %s\n", archivo);
  815     DBHashTable *dbh;
  816     int fd;
  817     if(mode) {
  818         fd = my_open (archivo, O_RDWR);
  819     } else {
  820         fd = my_open (archivo, O_RDONLY);
  821     }
  822 
  823 
  824 
  825     if(fd < 0) {
  826         DBG ("open(%s) %s failed: %s\n", archivo, (mode)?"O_RDWR":"O_RDONLY", strerror (errno));
  827         return NULL;
  828     }
  829     dbh = (DBHashTable *) malloc (sizeof (DBHashTable));
  830      if (dbh == NULL) {
  831     DBG( "malloc(%ld) failed: %s\n", (long)sizeof (DBHashTable), strerror(errno));
  832         close(fd);
  833         return NULL;
  834      }          
  835     memset (dbh, 0, sizeof (DBHashTable));
  836     dbh->lock_attempt_limit = open_timeout;
  837     dbh->fd = fd;
  838 
  839     /////////////////////////////////////////////
  840 #ifdef PARALLEL_SAFE
  841     if (flags & DBH_PARALLEL_SAFE){
  842         char *nsem_name = sem_name(archivo);
  843         if (!nsem_name) {
  844         DBG( "sem_name(%s) failed: %s\n", archivo, strerror(errno));
  845             dbh_close(dbh);
  846             return NULL;
  847         }
  848         dbh->sem = sem_open(nsem_name, O_CREAT, 0700, 1);
  849         free(nsem_name);
  850         dbh->lock_p = open_shm_lock(archivo);
  851     }
  852 #endif
  853 
  854     dbh->head_info = (dbh_header_t *) malloc (sizeof (dbh_header_t));
  855      if (dbh->head_info == NULL) {
  856     DBG( "malloc(%ld) failed: %s\n", (long)sizeof (dbh_header_t), strerror(errno));
  857         dbh_close(dbh);
  858         return NULL;
  859      }      
  860     FILE_POINTER eof = place_eof (dbh);
  861     if(eof < 0) {
  862     DBG( "place_eof(%s) failed: %s\n", archivo, strerror(errno));
  863         dbh_close(dbh);
  864         return NULL;
  865     }
  866 
  867     dbh->path = (char *)malloc (strlen (archivo) + 1);
  868      if (dbh->path == NULL) {
  869     DBG( "malloc(%ld) failed: %s\n", (long)(strlen (archivo) + 1), strerror(errno));
  870         dbh_close(dbh);
  871         return NULL;
  872      }     
  873      strcpy (dbh->path, archivo);
  874 
  875     if(!sdbh_readheader (dbh)) {
  876         dbh_close(dbh);
  877     DBG( "readheader(%s) failed: %s\n", archivo, strerror(errno));
  878         return NULL;
  879     }
  880     dbh->operate = sdbh_operate;
  881     dbh->branch = (FILE_POINTER *) malloc (dbh->head_info->n_limit * sizeof (FILE_POINTER));
  882      if (dbh->branch  == NULL) {
  883     ERR( "malloc dbh->branch: %s\n", strerror(errno));
  884         dbh_close(dbh);
  885         return NULL;
  886      }     
  887     dbh->newbranch = (FILE_POINTER *) malloc (dbh->head_info->n_limit * sizeof (FILE_POINTER));
  888      if (dbh->newbranch  == NULL) {
  889     ERR( "malloc dbh->newbranch: %s\n", strerror(errno));
  890         dbh_close(dbh);
  891         return NULL;
  892      }     
  893     dbh->key = (unsigned char *)malloc (dbh->head_info->n_limit);
  894       if (dbh->key == NULL) {
  895      ERR( "malloc dbh->key: %s\n", strerror(errno));
  896         dbh_close(dbh);
  897         return NULL;
  898      }     
  899    dbh->newkey = (unsigned char *)malloc (dbh->head_info->n_limit);
  900      if (dbh->newkey  == NULL) {
  901      ERR( "malloc dbh->newkey: %s\n", strerror(errno));
  902         dbh_close(dbh);
  903         return NULL;
  904      }     
  905     if(mode == WRITE)
  906         dbh->head_info->writeOK = 1;
  907     else
  908         dbh->head_info->writeOK = 0;
  909     sdbh_size (dbh, (int)dbh->head_info->record_length);
  910     DBG (" opened %s \n", archivo);
  911     return dbh;
  912 }  /****************************************************************************/
  913 
  914 static void
  915 sdbh_cuenta (unsigned char *numero, unsigned char orden, FILE_POINTER cuanto) {
  916     unsigned char q;
  917     FILE_POINTER m;
  918     if(orden == 0)
  919         numero[0] = 0;
  920     if(orden == 1)
  921         numero[0] = (unsigned char)cuanto;
  922     q = sdbh_cuantumR (cuanto, orden, &m);       /* en que cuantum estamos */
  923     orden--;
  924     sdbh_cifra (numero, q, orden, &m);
  925 /* sdbh_cifra(numero,q,orden-1,&m);*/
  926 } /***********************************************************************/
  927 
  928 #define RECORD_EXTENT  ( 2 + sizeof(FILE_POINTER)*(*how_many_branches+1) + dbh->head_info->n_limit + the_user_databytes )
  929 static FILE_POINTER
  930 sdbh_write (char newinfo, DBHashTable * dbh, unsigned char write_branches) {
  931     TRACE ("sdbh_write\n");
  932     int i;
  933     void *the_data;
  934     unsigned char *how_many_branches;
  935     FILE_POINTER the_user_databytes;
  936     FILE_POINTER *the_branches;
  937     unsigned char *the_key;
  938     if(newinfo) {
  939         the_branches = dbh->newbranch;
  940     } else {
  941         the_branches = dbh->branch;
  942     }
  943     the_data = dbh->data;
  944     how_many_branches = &(dbh->newbranches);
  945     the_user_databytes = dbh->bytes_userdata;
  946     the_key = dbh->key;
  947 
  948     if(the_user_databytes > dbh->head_info->record_length) {
  949         ERR(
  950                  "dbh->bytes_userdata (%lld) is greater than dbh->head_info->record_length (%lld). This is wrong and I stubbornly refuse to write\n",
  951                  (long long)dbh->bytes_userdata, (long long)dbh->head_info->record_length);
  952         ERR("*** sdbh_write() error 1\n");
  953         return 0;
  954     }
  955     DBG("Starting write at offset %lld\n", (long long)lseek(dbh->fd, 0, SEEK_CUR));
  956     if(write (dbh->fd, how_many_branches, 1) != 1){
  957         ERR("*** sdbh_write() error 2\n");
  958         return 0;
  959     }
  960     if(write (dbh->fd, &(dbh->flag), 1) != 1){
  961         ERR("*** sdbh_write() error 3\n");
  962         return 0;
  963     }
  964 
  965     i = write (dbh->fd, &the_user_databytes, sizeof (FILE_POINTER));
  966     if(i != sizeof (FILE_POINTER)){
  967         ERR("*** sdbh_write() error 4\n");
  968         return 0;
  969     }
  970 
  971     if(write_branches) {
  972 #ifdef TURN
  973         for(i = 0; i < *how_many_branches; i++)
  974             the_branches[i] = sdbh_turnaround (the_branches[i]);
  975 #endif
  976         i = write (dbh->fd, the_branches, sizeof (FILE_POINTER) * (*how_many_branches));
  977         if(i != sizeof (FILE_POINTER) * (*how_many_branches)){
  978                 ERR("*** sdbh_write() error 5\n");
  979                 return 0;
  980         }
  981 
  982 #ifdef TURN
  983         for(i = 0; i < *how_many_branches; i++)
  984             the_branches[i] = sdbh_turnaround (the_branches[i]);
  985 #endif
  986     } else {
  987         if(!advance_fp (dbh, *how_many_branches * sizeof (FILE_POINTER))){
  988         ERR("*** sdbh_write() error 6\n");
  989         return 0;
  990     }
  991 
  992 
  993     }
  994     if(write (dbh->fd, the_key, dbh->head_info->n_limit) != dbh->head_info->n_limit) {
  995         ERR( "fwrite: %s\n", strerror (errno));
  996         return 0;
  997     }
  998     if(the_user_databytes) {
  999         if(dbh->head_info->reservedC){
 1000             the_user_databytes = write (dbh->fd, the_data, dbh->head_info->record_length);
 1001     } else {
 1002             the_user_databytes = write (dbh->fd, the_data, the_user_databytes);
 1003     }
 1004         return (the_user_databytes);
 1005     } 
 1006         NOOP("*** sdbh_write() Data length for record is zero.\n");
 1007     return (0);
 1008     
 1009 }  /************************************************************************************/
 1010 
 1011 static int
 1012 sdbh_read (char newinfo, DBHashTable * dbh, unsigned char read_data) {
 1013     TRACE ("sdbh_read\n");
 1014     unsigned char keylength;
 1015     void *the_data;
 1016     unsigned char *how_many_branches;
 1017     FILE_POINTER *the_user_databytes;
 1018     FILE_POINTER *the_branches;
 1019     unsigned char *the_key;
 1020     if(newinfo) {
 1021         the_branches = dbh->newbranch;
 1022         the_data = dbh->newdata;
 1023         how_many_branches = &(dbh->newbranches);
 1024         the_user_databytes = &(dbh->newbytes_userdata);
 1025         the_key = dbh->newkey;
 1026     } else {
 1027         the_branches = dbh->branch;
 1028         the_data = dbh->data;
 1029         how_many_branches = &(dbh->branches);
 1030         the_user_databytes = &(dbh->bytes_userdata);
 1031         the_key = dbh->key;
 1032     }
 1033     keylength = dbh->head_info->n_limit;
 1034 
 1035     if (DBH_MAXIMUM_RECORD_SIZE(dbh) < 16 * 4096) {
 1036         /* new code: reduce read() call count from 3 to 1, 
 1037          *  but only with reasonable maximum data size (stack size is limited) 
 1038          *  the value 16 * 4096 is arbitrary, but sounds OK. */
 1039         /*  
 1040          * Minimum bytes to read: 2+sizeof(FILE_POINTER)
 1041          *   (unsigned char, unsigned char, FILE_POINTER)
 1042          * Maximum bytes to read: 2+sizeof(FILE_POINTER) + 256 + 256 * sizeof(FILE_POINTER)
 1043          *   (add 256 FILE_POINTERs and 256 unsigned chars for the key and maximum data size)
 1044          *    */
 1045         int min_bytes = 2+sizeof(FILE_POINTER);
 1046         int max_bytes = min_bytes + 256 + (256 * sizeof(FILE_POINTER)) + DBH_MAXIMUM_RECORD_SIZE(dbh);
 1047         unsigned char buffer[max_bytes];
 1048         int bytes = read (dbh->fd, buffer, max_bytes);
 1049         if (bytes < min_bytes){
 1050             DBG ("read error 2.1.1 (on empty dbh file this is OK)\n");
 1051             return 0;
 1052         }
 1053         memcpy(how_many_branches, buffer, 1);
 1054         memcpy(&(dbh->flag), buffer+1, 1);
 1055         memcpy (the_user_databytes, buffer+2, sizeof(FILE_POINTER));
 1056 #ifdef TURN
 1057             *the_user_databytes = sdbh_turnaround (*the_user_databytes);
 1058 #endif
 1059 
 1060         if(*the_user_databytes > dbh->head_info->record_length) {
 1061             ERR("sdbh_read(): user databytes is greater than head_info->record_length. This should not happen.\n");
 1062             return 0;
 1063         }
 1064         if(*the_user_databytes == 0) {
 1065             DBG ( "dbh_RECORD_SIZE() == 0. If this is not intentional, use dbh_set_recordsize() to set record size for %s.\n", 
 1066                     dbh->path);
 1067             return 0;
 1068         }
 1069         int structure_buffer_size = (sizeof (FILE_POINTER) * (*how_many_branches)) + keylength;
 1070         int correct_bytes = min_bytes + structure_buffer_size + *the_user_databytes;
 1071         if(bytes < correct_bytes) {
 1072             ERR ("fread error 2.4\n");
 1073             return 0;
 1074         }
 1075         void *structure_buffer = buffer + min_bytes;
 1076         memcpy(the_branches, structure_buffer, structure_buffer_size - keylength);
 1077         memcpy(the_key, structure_buffer + (structure_buffer_size - keylength), keylength);
 1078 #ifdef TURN
 1079         {
 1080             int i; for(i = 0; i < *how_many_branches; i++)
 1081                 the_branches[i] = sdbh_turnaround (the_branches[i]);
 1082         }
 1083 #endif
 1084         if(read_data) {
 1085             memcpy(the_data, structure_buffer + structure_buffer_size, *the_user_databytes);
 1086         }
 1087     } else {
 1088         int buffer_size = 2+sizeof(FILE_POINTER);
 1089         unsigned char buffer[buffer_size];
 1090         if(read (dbh->fd, buffer, buffer_size) != buffer_size) {
 1091             DBG ("read error 2.1.1 (on empty dbh file this is OK)\n");
 1092             return 0;
 1093         }
 1094         memcpy(how_many_branches, buffer, 1);
 1095         memcpy(&(dbh->flag), buffer+1, 1);
 1096         memcpy (the_user_databytes, buffer+2, sizeof(FILE_POINTER));
 1097 #ifdef TURN
 1098             *the_user_databytes = sdbh_turnaround (*the_user_databytes);
 1099 #endif
 1100 
 1101         if(*the_user_databytes > dbh->head_info->record_length) {
 1102             ERR("sdbh_read(): user databytes is greater than head_info->record_length. This should not happen.\n");
 1103             return 0;
 1104         }
 1105         if(*the_user_databytes == 0) {
 1106             ERR ( "dbh_RECORD_SIZE() == 0. If this is not intentional, use dbh_set_recordsize() to set record size for %s.\n", dbh->path);
 1107             return 0;
 1108         }
 1109 
 1110         int structure_buffer_size = (sizeof (FILE_POINTER) * (*how_many_branches)) + keylength;
 1111         unsigned char structure_buffer[structure_buffer_size];
 1112         if(read (dbh->fd, structure_buffer, structure_buffer_size) != structure_buffer_size) {
 1113             ERR ("fread error 2.4\n");
 1114             return 0;
 1115         }
 1116         memcpy(the_branches, structure_buffer, structure_buffer_size - keylength);
 1117         memcpy(the_key, structure_buffer + (structure_buffer_size - keylength), keylength);
 1118 #ifdef TURN
 1119         {
 1120             int i; for(i = 0; i < *how_many_branches; i++)
 1121                 the_branches[i] = sdbh_turnaround (the_branches[i]);
 1122         }
 1123 #endif
 1124         // This may be a very big read, better left by itself.
 1125         if(read_data) {
 1126             // if data is tainted, there will be no overrun since value is checked against
 1127             // dbh->head_info->record_length above.
 1128             // coverity[tainted_data : FALSE]
 1129             if(read (dbh->fd, the_data, *the_user_databytes) != *the_user_databytes) {
 1130                 ERR ("fread error 2.51: blocksize=%lld\n", (long long)(*the_user_databytes));
 1131 
 1132                 return 0;
 1133             }
 1134         }
 1135     }
 1136 // 
 1137     return 1;
 1138 } /************************************************************************************/
 1139 
 1140 static int
 1141 sdbh_readheader (DBHashTable * dbh) {
 1142     TRACE ("sdbh_readheader\n");
 1143     if(!place_fp_at (dbh, (off_t)0)) {
 1144             ERR("*** sdbh_readheader() error 1; !place_fp_at (dbh, 0)\n");
 1145         return 0;
 1146     }
 1147     // dbh->head_info is *not* a string. It is a fixed length structure
 1148     // coverity[string_null_argument : FALSE]
 1149     size_t bytes = read (dbh->fd, (void *)(dbh->head_info), sizeof (dbh_header_t));
 1150 
 1151     if (bytes != sizeof (dbh_header_t)) {
 1152         ERR( "Failed to read header for %s: %s\nsizeof (dbh_header_t)=%ld read=%ld\n", 
 1153                 dbh->path, strerror (errno),
 1154                  (long)sizeof (dbh_header_t), (long)bytes);
 1155         return 0;
 1156     }
 1157     if(strncmp (dbh->head_info->version, DBH_FILE_VERSION, 15) != 0) {
 1158         ERR(
 1159                  "Failed to read header for %s at sdbh_readheader(): strncmp (\"%s\",\"%s\")\n",
 1160                  dbh->path, dbh->head_info->version, DBH_FILE_VERSION);
 1161         return 0;
 1162     }
 1163     /* volatile values: */
 1164     dbh->head_info->user_tmpdir = 0;
 1165 
 1166 #ifdef TURN
 1167     dbh->head_info->bof = sdbh_turnaround (dbh->head_info->bof);
 1168     dbh->head_info->record_length = sdbh_turnaround (dbh->head_info->record_length);
 1169     dbh->head_info->total_space = sdbh_turnaround (dbh->head_info->total_space);
 1170     dbh->head_info->data_space = sdbh_turnaround (dbh->head_info->data_space);
 1171     dbh->head_info->erased_space = sdbh_turnaround (dbh->head_info->erased_space);
 1172     dbh->head_info->records = sdbh_turnaround (dbh->head_info->records);
 1173 #endif
 1174     return 1;
 1175 }  /************************************************************************************/
 1176 
 1177 #ifdef TURN
 1178 static FILE_POINTER
 1179 sdbh_turnaround (FILE_POINTER x) {
 1180     char *where,
 1181       temp;
 1182     where = (char *)&x;
 1183     temp = where[0];
 1184     where[0] = where[3];
 1185     where[3] = temp;
 1186     temp = where[1];
 1187     where[1] = where[2];
 1188     where[2] = temp;
 1189     return x;
 1190 } /************************************************************************************/
 1191 #endif
 1192 
 1193 static FILE_POINTER
 1194 sdbh_z (unsigned char n, unsigned char m) {      /* n=cuantum m=orden */
 1195     FILE_POINTER s = 0;
 1196     unsigned char i;
 1197     if(m < 2)
 1198         return 1;
 1199     if(m == 2)
 1200         return (n + 1);
 1201     m--;
 1202     for(i = n; i > 0; i--)
 1203         s += sdbh_z (i, m);
 1204 /* for (i=n;i>0;i--) s += sdbh_z(i,m-1);*/
 1205     return (s + 1);
 1206 }  /************************************************************************************/
 1207 
 1208 static unsigned char
 1209 sdbh_cuantumR (FILE_POINTER cuanto, unsigned char orden, FILE_POINTER * m) {
 1210     unsigned char i;
 1211     FILE_POINTER ztotal,
 1212       grandtotal = 0;
 1213     for(i = 0; 1; i++) {
 1214         if(i == orden)
 1215             ztotal = grandtotal;
 1216         else
 1217             ztotal = sdbh_z (i, orden);
 1218         grandtotal += ztotal;
 1219         if(cuanto <= grandtotal) {
 1220             if(m)
 1221                 *m = grandtotal - cuanto + 1;
 1222             break;
 1223         }
 1224     }
 1225     return i;
 1226 }  /************************************************************************************/
 1227 
 1228 static unsigned char
 1229 sdbh_cuantum (FILE_POINTER cuanto, unsigned char orden, FILE_POINTER * m) {
 1230     unsigned char i;
 1231     FILE_POINTER ztotal,
 1232       grandtotal = 0;
 1233     for(i = 0; 1; i++) {
 1234         if(i == orden)
 1235             ztotal = grandtotal;
 1236         else
 1237             ztotal = sdbh_z (i, orden);
 1238         grandtotal += ztotal;
 1239         if(cuanto <= grandtotal)
 1240             break;
 1241         if(m)
 1242             *m = cuanto - grandtotal;
 1243     }
 1244     return i;
 1245 }  /************************************************************************************/
 1246 
 1247 static void
 1248 sdbh_cifra (unsigned char *numero, unsigned char q, unsigned char orden, FILE_POINTER * m) {
 1249     unsigned char subcuantum;
 1250     int t;
 1251     if(orden == 1) {
 1252         t = q - (*m - 1);
 1253         numero[0] = (unsigned char)t;
 1254 /*  numero[0]=q - (*m-1);*/
 1255         t = *m - 1;
 1256         numero[1] = (unsigned char)t;
 1257 /*  numero[1]= *m-1;*/
 1258         return;
 1259     }
 1260     subcuantum = sdbh_cuantum (*m, orden, m);
 1261     t = q - subcuantum;
 1262     numero[0] = (unsigned char)t;
 1263 /* numero[0]=q-subcuantum;*/
 1264     orden--;
 1265     sdbh_cifra (numero + 1, subcuantum, orden, m);
 1266     /* sdbh_cifra(numero+1,subcuantum,orden-1,m); */
 1267     return;
 1268 }  /************************************************************************************/
 1269 
 1270 #if 0
 1271 // legacy code
 1272 static int
 1273 sdbh_barrelong (DBHashTable * dbh, FILE_POINTER startadd, int ramas) {
 1274     unsigned char i;
 1275     if(dbh_load_address (dbh, startadd) == 0)
 1276         return 0;
 1277     if(dbh->head_info->dbh_exit)
 1278         return 2;
 1279     if(!ERASED || (ERASED && dbh->head_info->sweep_erased))
 1280         (*(dbh->operate)) (dbh);
 1281     if(ramas) {
 1282         if((ramas = dbh->branches - ramas) < 0)
 1283             ramas = 0;
 1284     }
 1285     for(i = dbh->branches; i > ramas; i--) {
 1286         if(dbh->branch[i - 1])
 1287             sdbh_barrelong (dbh, dbh->branch[i - 1], 0);
 1288         dbh_load_address (dbh, startadd);
 1289     }
 1290     return 1;
 1291 }    /**********************************************************************/
 1292 
 1293 static int
 1294 sdbh_reversebarrelong (DBHashTable * dbh, FILE_POINTER startadd, int ramas) {
 1295     int i;
 1296     if(dbh_load_address (dbh, startadd) == 0)
 1297         return 0;
 1298     if(dbh->head_info->dbh_exit)
 1299         return 2;
 1300     if(!ERASED || (ERASED && dbh->head_info->sweep_erased))
 1301         (*(dbh->operate)) (dbh);
 1302 /* if (!ERASED) (*(dbh->operate))(dbh);*/
 1303     if(ramas) {
 1304         if((ramas = dbh->branches - ramas) < 0)
 1305             ramas = 0;
 1306     }
 1307     for(i = ramas; i < dbh->branches; i++) {
 1308         if(dbh->branch[i])
 1309             sdbh_reversebarrelong (dbh, dbh->branch[i], 0);
 1310         dbh_load_address (dbh, startadd);
 1311     }
 1312     return 1;
 1313 }   /******************************************************************************/
 1314 #endif
 1315 
 1316 static int
 1317 sdbh_reversebarre (DBHashTable * dbh, FILE_POINTER startadd, int ramas) {
 1318     int i;
 1319     unsigned char oldbranches;
 1320     FILE_POINTER *oldbranch;
 1321     if(dbh_load_address (dbh, startadd) == 0)
 1322         return 0;
 1323     if(dbh->head_info->dbh_exit)
 1324         return 2;
 1325     if(!ERASED || (ERASED && dbh->head_info->sweep_erased))
 1326         (*(dbh->operate)) (dbh);
 1327 /* if (!ERASED) (*(dbh->operate))(dbh);*/
 1328     oldbranch = (FILE_POINTER *) malloc (dbh->branches * sizeof (FILE_POINTER));
 1329      if (oldbranch == NULL) {
 1330      ERR( "malloc oldbranch: %s\n", strerror(errno));
 1331         return 0;
 1332      }     
 1333     oldbranches = dbh->branches;
 1334     if(ramas) {
 1335         if((ramas = dbh->branches - ramas) < 0)
 1336             ramas = 0;
 1337     }
 1338 #if 1
 1339     for(i = 0; i < oldbranches; i++)
 1340         oldbranch[i] = dbh->branch[i];
 1341     for(i = ramas; i < oldbranches; i++)
 1342         if(oldbranch[i])
 1343             sdbh_reversebarre (dbh, oldbranch[i], 0);
 1344     free (oldbranch);
 1345 #else
 1346 // legacy code
 1347     if(oldbranch == NULL) fullmemory = 1;
 1348     char fullmemory = 0;
 1349     if(!fullmemory) {
 1350         for(i = 0; i < oldbranches; i++)
 1351             oldbranch[i] = dbh->branch[i];
 1352         for(i = ramas; i < oldbranches; i++)
 1353             if(oldbranch[i])
 1354                 sdbh_reversebarre (dbh, oldbranch[i], 0);
 1355         free (oldbranch);
 1356     } else
 1357         for(i = ramas; i < oldbranches; i++) {
 1358             if(dbh->branch[i])
 1359                 sdbh_reversebarrelong (dbh, dbh->branch[i], 0);
 1360             dbh_load_address (dbh, startadd);
 1361         }
 1362 #endif
 1363     return 1;
 1364 }  /******************************************************************************/
 1365 
 1366 static int
 1367 sdbh_barre (DBHashTable * dbh, FILE_POINTER startadd, int ramas) {
 1368     unsigned char i;
 1369     FILE_POINTER *oldbranch;
 1370     if(dbh_load_address (dbh, startadd) == 0)
 1371         return 0;
 1372     if(dbh->head_info->dbh_exit)
 1373         return 2;
 1374 #if 0
 1375     printf ("barre: currentseek at %lu\n", (long unsigned)startadd);
 1376     printf ("record is erased? -> %d\n", ERASED);
 1377 #endif
 1378     if(!ERASED || (ERASED && dbh->head_info->sweep_erased))
 1379         (*(dbh->operate)) (dbh);
 1380 /* if (!ERASED) (*(dbh->operate))(dbh);*/
 1381     oldbranch = (FILE_POINTER *) malloc (dbh->branches * sizeof (FILE_POINTER));
 1382       if (oldbranch == NULL) {
 1383      ERR( "malloc oldbranch: %s\n", strerror(errno));
 1384         return 0;
 1385      }     
 1386     if(ramas) {
 1387         if((ramas = dbh->branches - ramas) < 0)
 1388             ramas = 0;
 1389     }
 1390 #if 1
 1391     for(i = 0; i < dbh->branches; i++)
 1392         oldbranch[i] = dbh->branch[i];
 1393     for(i = dbh->branches; i > ramas; i--)
 1394         if(oldbranch[i - 1])
 1395             sdbh_barre (dbh, oldbranch[i - 1], 0);
 1396     free (oldbranch);
 1397 #else
 1398 // legacy code
 1399     char fullmemory = 0;
 1400     if(!fullmemory) {
 1401         for(i = 0; i < dbh->branches; i++)
 1402             oldbranch[i] = dbh->branch[i];
 1403         for(i = dbh->branches; i > ramas; i--)
 1404             if(oldbranch[i - 1])
 1405                 sdbh_barre (dbh, oldbranch[i - 1], 0);
 1406         free (oldbranch);
 1407     } else
 1408         for(i = dbh->branches; i > ramas; i--) {
 1409             if(dbh->branch[i - 1])
 1410                 sdbh_barrelong (dbh, dbh->branch[i - 1], 0);
 1411             dbh_load_address (dbh, startadd);
 1412         }
 1413 #endif
 1414     return 1;
 1415 }   /************************************************************************/
 1416 
 1417   /* Functions: */
 1418 static void
 1419 sdbh_transfer (DBHashTable * srcdbh) {
 1420     DBHashTable *dbh_desdbh = srcdbh->dbh_desdbh;
 1421     dbh_desdbh->bytes_userdata = srcdbh->bytes_userdata;
 1422     dbh_update (dbh_desdbh);
 1423 /* if ((count++ % 100)==0) printf("\n %ld registros procesados",count);*/
 1424     return;
 1425 } /***************************************************************************/
 1426 
 1427 /*****************************************************************************/
 1428 /***    old   non static functions ***/
 1429 /*****************************************************************************/
 1430 
 1431 static int
 1432 sdbh_size (DBHashTable * dbh, FILE_POINTER record_length) {
 1433 
 1434     /* despues de abrir DBHashTable */
 1435     if(dbh == NULL) {
 1436         ERR( "sdbh_size(): dbh != NULL not met\n");
 1437         return 0;
 1438     }
 1439     if(dbh->head_info == NULL) {
 1440         ERR( "sdbh_size(): dbh->head_info != NULL not met\n");
 1441         return 0;
 1442     }
 1443 
 1444     if(record_length < dbh->head_info->record_length) {
 1445         /*
 1446         ERR ("sdbh_size(): may not shrink! current size=%lld requested size=%ld\n",
 1447                (long long)dbh->head_info->record_length, (long)record_length);
 1448                */
 1449         return 0;
 1450     }
 1451 
 1452     void *data = malloc (record_length);
 1453      if (data == NULL) {
 1454      ERR( "malloc data: %s\n", strerror(errno));
 1455         return 0;
 1456      }     
 1457     void *newdata = malloc (record_length);
 1458      if (newdata == NULL) {
 1459          free(data);
 1460      ERR( "malloc newdata: %s\n", strerror(errno));
 1461         return 0;
 1462      }     
 1463     memset (data, 0, record_length);
 1464     memset (newdata, 0, record_length);
 1465     if(dbh->data != NULL) {
 1466         memcpy (data, dbh->data, dbh->head_info->record_length);
 1467         free (dbh->data);
 1468     }
 1469     if(dbh->newdata != NULL) {
 1470         memcpy (newdata, dbh->newdata, dbh->head_info->record_length);
 1471         free (dbh->newdata);
 1472     }
 1473     dbh->data = data;
 1474     dbh->newdata = newdata;
 1475 
 1476     if (dbh->head_info->record_length != record_length) {
 1477     dbh->head_info->record_length = record_length;
 1478         if(dbh->head_info->writeOK) sdbh_writeheader (dbh, 1);
 1479     }
 1480     return 1;
 1481 } /****************************************************************************************/
 1482 
 1483 #if 0
 1484 // legacy code
 1485 static int
 1486 sdbh_barrelong2 (DBHashTable * dbh, DBHashFunc2 operate, void *data, 
 1487         FILE_POINTER startadd, int ramas) {
 1488     unsigned char i;
 1489     if(dbh_load_address (dbh, startadd) == 0)
 1490         return 0;
 1491     if(dbh->head_info->dbh_exit)
 1492         return 2;
 1493     if(!ERASED || (ERASED && dbh->head_info->sweep_erased))
 1494         (*(dbh->operate)) (dbh);
 1495     if(ramas) {
 1496         if((ramas = dbh->branches - ramas) < 0)
 1497             ramas = 0;
 1498     }
 1499     for(i = dbh->branches; i > ramas; i--) {
 1500         if(dbh->branch[i - 1])
 1501             sdbh_barrelong2 (dbh, operate, data, dbh->branch[i - 1], 0);
 1502         dbh_load_address (dbh, startadd);
 1503     }
 1504     return 1;
 1505 }    /**********************************************************************/
 1506 #endif
 1507 
 1508 static int
 1509 sdbh_barre2 (DBHashTable * dbh, DBHashFunc2 operate, void *data, 
 1510     FILE_POINTER startadd, int ramas) {
 1511     unsigned char i;
 1512     FILE_POINTER *oldbranch;
 1513     if(dbh_load_address (dbh, startadd) == 0)
 1514         return 0;
 1515     if(dbh->head_info->dbh_exit)
 1516         return 2;
 1517 #if 0
 1518     printf ("barre: currentseek at %lu\n", (long unsigned)startadd);
 1519     printf ("record is erased? -> %d\n", ERASED);
 1520 #endif
 1521     if(!ERASED || (ERASED && dbh->head_info->sweep_erased))
 1522         (operate) (dbh, data);
 1523 /* if (!ERASED) (*(dbh->operate))(dbh);*/
 1524     oldbranch = (FILE_POINTER *) malloc (dbh->branches * sizeof (FILE_POINTER));
 1525       if (oldbranch == NULL) {
 1526      ERR( "malloc oldbranch: %s\n", strerror(errno));
 1527         return 0;
 1528      }     
 1529     if(ramas) {
 1530         if((ramas = dbh->branches - ramas) < 0)
 1531             ramas = 0;
 1532     }
 1533 #if 1
 1534     for(i = 0; i < dbh->branches; i++)
 1535         oldbranch[i] = dbh->branch[i];
 1536     for(i = dbh->branches; i > ramas; i--)
 1537         if(oldbranch[i - 1])
 1538             sdbh_barre2 (dbh, operate, data, oldbranch[i - 1], 0);
 1539     free (oldbranch);
 1540 #else
 1541 // legacy code
 1542     char fullmemory = 0;
 1543     if(!fullmemory) 
 1544     {
 1545         for(i = 0; i < dbh->branches; i++)
 1546             oldbranch[i] = dbh->branch[i];
 1547         for(i = dbh->branches; i > ramas; i--)
 1548             if(oldbranch[i - 1])
 1549                 sdbh_barre2 (dbh, operate, data, oldbranch[i - 1], 0);
 1550         free (oldbranch);
 1551     } else
 1552         for(i = dbh->branches; i > ramas; i--) {
 1553             if(dbh->branch[i - 1])
 1554                 sdbh_barrelong2 (dbh, operate, data, dbh->branch[i - 1], 0);
 1555             dbh_load_address (dbh, startadd);
 1556         }
 1557 #endif
 1558     return 1;
 1559 }   /************************************************************************/
 1560 
 1561 
 1562 static int
 1563 sdbh_newbarre2 (DBHashTable * dbh, DBHashFunc2 operate, void *data) {
 1564     if(!dbh) {
 1565         ERR( "sdbh_newbarre(): %s\n", strerror (EBADF));
 1566         return 0;
 1567     }
 1568 
 1569     dbh->head_info->dbh_exit = 0;
 1570     sdbh_barre2 (dbh, operate, data, dbh->head_info->bof, 0);
 1571 
 1572 
 1573 
 1574     return 1;
 1575 } /***************************************************************************************/
 1576 
 1577 static int
 1578 sdbh_newbarre (DBHashTable * dbh, unsigned char *key1, unsigned char *key2, unsigned char keylength) {
 1579     int i;
 1580     FILE_POINTER pointer;
 1581     if(!dbh) {
 1582         ERR( "sdbh_newbarre(): %s\n", strerror (EBADF));
 1583 
 1584         return 0;
 1585     }
 1586 
 1587     dbh->head_info->dbh_exit = 0;
 1588     if(key1 == NULL) {
 1589         sdbh_barre (dbh, dbh->head_info->bof, 0);
 1590         return 1;
 1591     }
 1592     if(key2 != NULL) {
 1593         memcpy ((void *)(dbh->key), (void *)key1, dbh->head_info->n_limit);
 1594 
 1595         for(i = 0; i < dbh->head_info->n_limit; i++)
 1596             if(key1[i] != key2[i])
 1597                 break;
 1598         /* que pedo con ERASED?? (load returns errorvalue on ERASED */
 1599         pointer = dbh_load (dbh);
 1600         if((pointer == 0) && !(ERASED))
 1601             return 0;
 1602 /*  if ((pointer=dbh_load(dbh)) == 0) return 0;*/
 1603         /* aqui hay que considerar que el nodo puede estar marcado como ERASED */
 1604         else {
 1605             pointer = dbh_find (dbh, i);
 1606             sdbh_barre (dbh, pointer, dbh->head_info->n_limit - i);
 1607         }
 1608     } else if(keylength) {
 1609         memcpy ((void *)(dbh->key), (void *)key1, keylength);
 1610         pointer = dbh_find (dbh, keylength);
 1611         if(pointer == 0)
 1612             return 0;
 1613         sdbh_barre (dbh, pointer, dbh->head_info->n_limit - keylength);
 1614     }
 1615     return 1;
 1616 } /***************************************************************************************/
 1617 
 1618 static int
 1619 sdbh_newreversebarre (DBHashTable * dbh, unsigned char *key1, unsigned char *key2, unsigned char keylength) {
 1620     int i;
 1621     FILE_POINTER pointer;
 1622     if(!dbh) {
 1623         ERR( "sdbh_newreversebarre(): %s\n", strerror (EBADF));
 1624 
 1625         return 0;
 1626     }
 1627 
 1628     dbh->head_info->dbh_exit = 0;
 1629     if(key1 == NULL) {
 1630         sdbh_reversebarre (dbh, dbh->head_info->bof, 0);
 1631         return 1;
 1632     }
 1633     if(key2 != NULL) {
 1634         memcpy ((void *)(dbh->key), (void *)key1, dbh->head_info->n_limit);
 1635         for(i = 0; i < dbh->head_info->n_limit; i++)
 1636             if(key1[i] != key2[i])
 1637                 break;
 1638         /* que pedo con ERASED?? (load returns errorvalue on ERASED */
 1639         pointer = dbh_load (dbh);
 1640         if((pointer == 0) && !(ERASED))
 1641             return 0;
 1642 /*  if ((pointer=dbh_load(dbh)) == 0) return 0;*/
 1643         else {
 1644             pointer = dbh_find (dbh, i);
 1645             sdbh_reversebarre (dbh, pointer, i);
 1646         }
 1647     } else if(keylength != 0) {
 1648         memcpy ((void *)dbh->key, (void *)key1, keylength);
 1649 
 1650         pointer = dbh_find (dbh, keylength);
 1651         if(pointer == 0)
 1652             return 0;
 1653         sdbh_reversebarre (dbh, pointer, keylength);
 1654     }
 1655     return 1;
 1656 }  /************************************************************************************/
 1657 
 1658 static DBHashTable *
 1659 sdbh_regen (DBHashTable * dbh, int sweep) {
 1660     void *temp, *newtemp;
 1661     char *archivo2, *archivo;
 1662     DBHashTable *newdbh;
 1663     unsigned char *tempkey, *newtempkey;
 1664     void (*fun) (DBHashTable *);
 1665 
 1666     if(!dbh) {
 1667         ERR( "sdbh_regen(): %s\n", strerror (EBADF));
 1668         return NULL;
 1669     }
 1670     if (dbh->protection_flags & DBH_READ_ONLY){
 1671         ERR( "DBH table is read only: %s\n", dbh->path);
 1672         return NULL;
 1673     }
 1674     dbh_lock_write (dbh);
 1675 
 1676     archivo2 = sdbh_randomfilename (dbh, 's');
 1677     if (!archivo2){
 1678         ERR( "Cannot open temporary file: DBHashtable will not be regenerated\n");
 1679     return NULL;
 1680     }
 1681 
 1682     archivo = (char *)malloc (strlen (dbh->path) + 1);
 1683     if (archivo == NULL) {
 1684      ERR( "malloc(%ld): %s\n", (long)(strlen (dbh->path) + 1), strerror(errno));
 1685     free(archivo2);
 1686         return NULL;
 1687     } 
 1688     strcpy (archivo, dbh->path);
 1689     struct stat  st_old;
 1690     // No problem with TOCTOU, since at TOU, rename will return error
 1691     // if synchronization mismatch occurs.
 1692     // coverity[fs_check_call : FALSE]
 1693     if (stat (archivo, &st_old) < 0){
 1694         ERR( "unable to stat: %s\n", archivo);
 1695     free(archivo);
 1696     free(archivo2);
 1697         return NULL;
 1698     }
 1699 
 1700     char *archivobak = (char *)malloc (strlen (archivo) + strlen (".bak") + 1);
 1701     if (archivobak == NULL) {
 1702     free(archivo);
 1703     free(archivo2);
 1704      ERR( "malloc archivobak: %s\n", strerror(errno));
 1705         return NULL;
 1706     }     
 1707     sprintf (archivobak, "%s.bak", archivo);
 1708 
 1709     // Set thread safe characteristics to new table.
 1710     int flags = dbh->protection_flags & (DBH_PARALLEL_SAFE|DBH_THREAD_SAFE);
 1711     DBHashTable *dbh_desdbh = sdbh_create (archivo2, dbh->head_info->n_limit, flags);
 1712     if(!dbh_desdbh) {
 1713         ERR( "Cannot open for write: %s\n", archivo2);
 1714     free(archivo);
 1715     free(archivo2);
 1716     free(archivobak);
 1717         return NULL;
 1718     }
 1719     
 1720     struct stat  st_new;
 1721     // No problem with TOCTOU, since at TOU, rename will return error
 1722     // if synchronization mismatch occurs.
 1723     // coverity[fs_check_call : FALSE]
 1724     if (stat (archivo2, &st_new) < 0){
 1725         ERR( "unable to stat: %s\n", archivo2);
 1726     free(archivo);
 1727     free(archivo2);
 1728     free(archivobak);
 1729         dbh_close(dbh_desdbh);
 1730         return NULL;
 1731     }
 1732     dbh_lock_write (dbh_desdbh);
 1733 
 1734     
 1735     dbh->dbh_desdbh = dbh_desdbh;
 1736 
 1737     tempkey = dbh_desdbh->key;
 1738     newtempkey = dbh_desdbh->newkey;
 1739     temp = dbh_desdbh->data;
 1740     newtemp = dbh_desdbh->newdata;
 1741     dbh_desdbh->key = dbh->key;
 1742     dbh_desdbh->newkey = dbh->newkey;
 1743     dbh_desdbh->data = dbh->data;
 1744     dbh_desdbh->newdata = dbh->newdata;
 1745 
 1746     
 1747 
 1748     dbh_desdbh->head_info->record_length = dbh->head_info->record_length;
 1749     fun = dbh->operate;
 1750 
 1751     dbh->operate = sdbh_transfer;
 1752     if(sweep) {
 1753         sdbh_newbarre (dbh, NULL, NULL, 0);
 1754     } else {
 1755         sdbh_newreversebarre (dbh, NULL, NULL, 0);
 1756     }
 1757 
 1758     dbh_desdbh->data = temp;
 1759     dbh_desdbh->newdata = newtemp;
 1760     dbh_desdbh->key = tempkey;
 1761     dbh_desdbh->newkey = newtempkey;
 1762 
 1763     dbh_unlock_write (dbh_desdbh);
 1764     dbh_close (dbh_desdbh);
 1765     dbh_unlock_write (dbh);
 1766     dbh_close (dbh);
 1767 
 1768 
 1769   
 1770     
 1771     if(unlink (archivobak) < 0 && errno != ENOENT) {
 1772             ERR( "cannot remove old backup file: %s (%s)\n",
 1773                             archivobak, strerror(errno));
 1774     }
 1775 
 1776     DBG ("rename %s %s\n", archivo, archivobak);
 1777     if(rename (archivo, archivobak) < 0) {
 1778             ERR( "*** DBH: cannot rename %s to %s (%s)\n",
 1779                             archivo, archivobak, strerror (errno));            ;
 1780     }
 1781     free (archivobak);
 1782 
 1783     if(st_old.st_dev == st_new.st_dev) {
 1784         DBG (" rename %s %s\n", archivo2, archivo);
 1785         if(rename (archivo2, archivo) < 0) {
 1786             ERR( "*** DBH: cannot rename %s to %s (%s)\n",
 1787                             archivo2, archivo, strerror (errno));
 1788         }
 1789     } else {
 1790         DBG (" mv %s %s\n", archivo2, archivo);
 1791 #ifdef HAVE_FORK
 1792         pid_t pid = fork ();
 1793         if(!pid) {
 1794             execlp ("mv", "mv", archivo2, archivo, NULL);
 1795             _exit (123);
 1796         } else {
 1797             int status;
 1798             waitpid (pid, &status, 0);
 1799         }
 1800 #else
 1801 # ifdef HAVE__SPAWNVP
 1802     const int mode = P_WAIT; // also P_NOWAIT
 1803     const char *_argv[]={"copy", archivo2, archivo, NULL};
 1804     const char *argv0 = _argv[0];
 1805     _spawnvp (mode, argv0, _argv);
 1806 # else
 1807         ERR( "Cannot regenerate %s\n", archivo);
 1808         free (archivo);
 1809         free (archivo2);
 1810         return NULL;
 1811 # endif
 1812 #endif
 1813     }
 1814 
 1815     newdbh = dbh_new (archivo, NULL, flags);
 1816     free (archivo);
 1817     free (archivo2);
 1818     newdbh->operate = fun;
 1819     return newdbh;
 1820 }
 1821 
 1822 static void
 1823 prune_mark_erased (DBHashTable * dbh) {
 1824     SET_ERASED;
 1825     /* set file pointer at record flag byte */
 1826     if(place_fp_at (dbh, (off_t)((dbh->reservedB) + 1)) < 0) {
 1827         return;
 1828     }
 1829     /* write the flag to the file */
 1830     /* printf("flag for erase=0x%x\n",dbh->flag); */
 1831     if(write (dbh->fd, &(dbh->flag), 1) != 1) {
 1832         ERR( "unable to erase: %s\n", strerror (errno));
 1833         return;
 1834     }
 1835     /*printf("erasing %s flag at %lu\n",(char *)dbh->data,
 1836        (long unsigned)(dbh->reservedB+1)); */
 1837     /* update file header information */
 1838     dbh->head_info->data_space -= dbh->bytes_userdata;
 1839     dbh->head_info->erased_space += (dbh->bytes_userdata);
 1840     return;
 1841 }
 1842 
 1843 static void
 1844 prune_mark_unerased (DBHashTable * dbh) {
 1845     SET_UNERASED;
 1846     /* set file pointer at record flag byte */
 1847     if(place_fp_at (dbh, (off_t)(dbh->reservedB + 1)) < 0){
 1848         return;
 1849     }
 1850     /* write the flag to the file */
 1851     if(write (dbh->fd, &(dbh->flag), 1) != 1) {
 1852         ERR( "unable to unerase: %s\n", strerror (errno));
 1853         return;
 1854     }
 1855     /* update file header information */
 1856     dbh->head_info->data_space += dbh->bytes_userdata;
 1857     dbh->head_info->erased_space -= (dbh->bytes_userdata);
 1858     return;
 1859 }
 1860 
 1861 
 1862 static int sdbh_writeheader (DBHashTable * dbh, int flush) {
 1863         TRACE("sdbh_writeheader\n");
 1864     if(!dbh || !(dbh->head_info)) {
 1865         ERR("sdbh_writeheader(): %s\n", strerror (EBADF));
 1866         return 0;
 1867     }
 1868     if(!(dbh->head_info->writeOK)){
 1869     ERR("sdbh_writeheader() is invalid in a read only DBH Table\n");
 1870     return 0;
 1871     }   
 1872 
 1873     if(strlen (COPYRIGHT) > 127) {
 1874         ERR("This should never happen, strlen(\"%s\")>127\n", COPYRIGHT);
 1875         return 0;
 1876     }
 1877     if (!strlen(dbh->head_info->copyright)){
 1878             strcpy ((char *)(dbh->head_info->copyright), COPYRIGHT);
 1879     }
 1880 
 1881 #ifdef TURN
 1882     dbh->head_info->bof = sdbh_turnaround (dbh->head_info->bof);
 1883     dbh->head_info->record_length = sdbh_turnaround (dbh->head_info->record_length);
 1884     dbh->head_info->total_space = sdbh_turnaround (dbh->head_info->total_space);
 1885     dbh->head_info->data_space = sdbh_turnaround (dbh->head_info->data_space);
 1886     dbh->head_info->erased_space = sdbh_turnaround (dbh->head_info->erased_space);
 1887     dbh->head_info->records = sdbh_turnaround (dbh->head_info->records);
 1888     dbh->head_info->fractalidad = sdbh_turnaround (dbh->head_info->fractalidad);
 1889 #endif
 1890 
 1891 
 1892     dbh_lock_write (dbh);
 1893     if(!place_fp_at (dbh, (off_t)0)){
 1894         dbh_unlock_write (dbh);
 1895         ERR("*** sdbh_writeheader(): error 1; cannot place at 0L\n");
 1896         return 0;
 1897     }
 1898 
 1899 
 1900     size_t bytes = write (dbh->fd, (void *)dbh->head_info, sizeof (dbh_header_t));
 1901     if(bytes != sizeof (dbh_header_t)) {
 1902         dbh_unlock_write (dbh);
 1903         ERR("*** sdbh_writeheader(): error 2; write count %lu != %lu\n",
 1904                         (long unsigned)sizeof (dbh_header_t), 
 1905                         (long unsigned)bytes);
 1906         return 0;
 1907     }
 1908     dbh_unlock_write (dbh);
 1909 
 1910 
 1911 #ifdef TURN
 1912     dbh->head_info->bof = sdbh_turnaround (dbh->head_info->bof);
 1913     dbh->head_info->record_length = sdbh_turnaround (dbh->head_info->record_length);
 1914     dbh->head_info->total_space = sdbh_turnaround (dbh->head_info->total_space);
 1915     dbh->head_info->data_space = sdbh_turnaround (dbh->head_info->data_space);
 1916     dbh->head_info->erased_space = sdbh_turnaround (dbh->head_info->erased_space);
 1917     dbh->head_info->records = sdbh_turnaround (dbh->head_info->records);
 1918     dbh->head_info->fractalidad = sdbh_turnaround (dbh->head_info->fractalidad);
 1919 #endif
 1920     if (!flush) return 1;
 1921   
 1922 #if HAVE_FSYNC
 1923     fsync(dbh->fd);
 1924 #endif
 1925 #if HAVE_WINDOWS_H
 1926     FlushFileBuffers ((HANDLE) _get_osfhandle (dbh->fd));
 1927 #endif
 1928     
 1929 #ifdef DEBUG_TRACE
 1930     dbh_header_t tmp;
 1931     lseek(dbh->fd, 0, SEEK_SET);
 1932     DBG("--- > testing written header... got %ld bytes\n",
 1933                     (long)read(dbh->fd, (void *)(&tmp), sizeof(dbh_header_t)));
 1934 #endif
 1935     return 1;
 1936 }
 1937 
 1938 #ifdef PARALLEL_SAFE
 1939 static int
 1940 lock_it (DBHashTable * dbh, int for_write){
 1941     TRACE("DBH: locking file %s (write = %d)\n", dbh->path, for_write);
 1942     if (for_write) {
 1943         dbh->lock_p->write_lock_count++;
 1944         dbh->lock_p->write_lock = getpid();
 1945     } else {
 1946         dbh->lock_p->read_lock_count++;
 1947     }
 1948     if(msync (dbh->lock_p,  sizeof(dbh_lock_t), MS_ASYNC) < 0){
 1949             ERR("(2:lock_p=%p) Cannot msync shared memory item for %s: %s\n", 
 1950                 dbh->lock_p, dbh->path, strerror (errno));
 1951     }
 1952     return 1;
 1953 }
 1954 
 1955 static int
 1956 lock_ok (DBHashTable * dbh, int for_write){
 1957     int lock_condition;
 1958     if (for_write){
 1959         lock_condition = (dbh->lock_p->read_lock_count ||
 1960         (dbh->lock_p->write_lock_count && dbh->lock_p->write_lock != getpid()));
 1961     } else {
 1962         lock_condition = dbh->lock_p->write_lock_count;
 1963     }
 1964     if (lock_condition) return 0;
 1965     return 1;
 1966 }
 1967 
 1968 static int
 1969 sdbh_lock (DBHashTable * dbh, int for_write){
 1970     if (!(dbh->protection_flags & DBH_PARALLEL_SAFE)){
 1971         return 0;
 1972     }
 1973     if (dbh->lock_attempt_limit == 0) sem_wait(dbh->sem);
 1974     else { 
 1975         struct timespec timeout;
 1976         timeout.tv_sec = time(NULL) + dbh->lock_attempt_limit;
 1977         timeout.tv_nsec = 0;
 1978         if (sem_timedwait(dbh->sem, &timeout) < 0){
 1979             ERR("DBH: sdbh_lock() unable to unlock semaphore for %s (%s), proceeding on timeout...\n", dbh->path, strerror(errno));
 1980         }
 1981     }
 1982     if (lock_ok(dbh, for_write)){
 1983         lock_it(dbh, for_write);
 1984         sem_post(dbh->sem);
 1985         return 1;
 1986     }
 1987     sem_post(dbh->sem);
 1988     return 0;
 1989 }
 1990 
 1991 static int
 1992 sdbh_unlock (DBHashTable * dbh, int for_write){
 1993     if (!(dbh->protection_flags & DBH_PARALLEL_SAFE)){
 1994         return 0;
 1995     }
 1996     if (dbh->lock_attempt_limit == 0) sem_wait(dbh->sem);
 1997     else { 
 1998         struct timespec timeout;
 1999         timeout.tv_sec = time(NULL) + dbh->lock_attempt_limit;
 2000         timeout.tv_nsec = 0;
 2001         if (sem_timedwait(dbh->sem, &timeout) < 0){
 2002             ERR("DBH: sdbh_unlock() unable to unlock semaphore for %s (%s), proceeding on timeout...\n", dbh->path, strerror(errno));
 2003         }
 2004     }
 2005     if (for_write){
 2006         dbh->lock_p->write_lock_count = 0;
 2007         dbh->lock_p->write_lock = 0;
 2008     } else {
 2009         if (dbh->lock_p->read_lock_count > 0) dbh->lock_p->read_lock_count--;
 2010     }
 2011     if(msync (dbh->lock_p,  sizeof(dbh_lock_t), MS_ASYNC) < 0){
 2012             ERR("(3:lock_p=%p) Cannot msync shared memory item for %s: %s\n", 
 2013                 dbh->lock_p, dbh->path, strerror (errno));
 2014     }
 2015     sem_post(dbh->sem);
 2016     return 1;
 2017 }
 2018 #endif
 2019