Exemplo n.º 1
0
   // close the database connection
   static void CloseHashStorage()
   {
      if ( ms_hashMap )
      {
         _hash_drv_close(ms_hashMap);
         free(ms_hashMap);
         ms_hashMap = NULL;

         _hash_drv_lock_free(&ms_hashLock, DSPAM_USER_NAME);
      }
   }
Exemplo n.º 2
0
int _hash_drv_autoextend(
    hash_drv_map_t map, 
    int extents, 
    unsigned long last_extent_size)
{
  struct _hash_drv_header header;
  struct _hash_drv_spam_record rec;
  int i, lastsize;

  _hash_drv_close(map);

  map->fd = open(map->filename, O_RDWR);
  if (map->fd < 0) {
    LOG(LOG_WARNING, "unable to resize hash. open failed: %s", strerror(errno));
    return EFAILURE;
  }

  memset(&header, 0, sizeof(struct _hash_drv_header));
  memset(&rec, 0, sizeof(struct _hash_drv_spam_record));
  
  if (extents == 0 || !map->pctincrease)
    header.hash_rec_max = map->extent_size;
  else
    header.hash_rec_max = last_extent_size
                   + (last_extent_size * (map->pctincrease/100.0));

  LOGDEBUG("adding extent last: %d(%ld) new: %d(%ld) pctincrease: %1.2f", extents, last_extent_size, extents+1, header.hash_rec_max, (map->pctincrease/100.0));

  lastsize=lseek (map->fd, 0, SEEK_END);
  if(write (map->fd, &header, sizeof(struct _hash_drv_header))!=sizeof(struct _hash_drv_header)) {
    ftruncate(map->fd,lastsize);
    close(map->fd);
    LOG(LOG_WARNING, "unable to resize hash. open failed: %s", strerror(errno));
    return EFAILURE;
  }
  for(i=0;i<header.hash_rec_max;i++) 
    if(write (map->fd, &rec, sizeof(struct _hash_drv_spam_record))!=sizeof(struct _hash_drv_spam_record)) {
      ftruncate(map->fd,lastsize);
      close(map->fd);
      LOG(LOG_WARNING, "unable to resize hash. open failed: %s", strerror(errno));
      return EFAILURE;
    }
  close(map->fd);

  _hash_drv_open(map->filename, map, 0, map->max_seek, 
      map->max_extents, map->extent_size, map->pctincrease, map->flags);
  return 0;
}
Exemplo n.º 3
0
int
_ds_shutdown_storage (DSPAM_CTX * CTX)
{
  struct _hash_drv_storage *s;
  struct nt_node *node_nt;
  struct nt_c c_nt;
  int lock_result;

  if (!CTX || !CTX->storage)
    return EINVAL;

  s  = (struct _hash_drv_storage *) CTX->storage;

  /* Close open file handles to directories (iteration functions) */

  node_nt = c_nt_first (s->dir_handles, &c_nt);
  while (node_nt != NULL)
  {
    DIR *dir;
    dir = (DIR *) node_nt->ptr;
    closedir (dir);
    node_nt = c_nt_next (s->dir_handles, &c_nt);
  }
  nt_destroy (s->dir_handles);

  if (CTX->operating_mode != DSM_CLASSIFY)
    _hash_drv_set_spamtotals (CTX);

  /* Close connection to hash database only if we're not concurrent */

  if (!s->dbh_attached) {
    _hash_drv_close(s->map);
    free(s->map);
    lock_result =
      _hash_drv_lock_free (s, (CTX->group) ? CTX->group : CTX->username);
    if (lock_result < 0)
      return EUNKNOWN;
  }

  free (CTX->storage);
  CTX->storage = NULL;

  return 0;
}
Exemplo n.º 4
0
int
dspam_shutdown_driver (DRIVER_CTX *DTX)
{
#ifdef DAEMON
  DSPAM_CTX *CTX;

  if (DTX && DTX->CTX) {
    char *HashConcurrentUser;
    CTX = DTX->CTX;
    HashConcurrentUser = READ_ATTRIB("HashConcurrentUser");

    if (DTX->flags & DRF_STATEFUL) {
      hash_drv_map_t map;
      int connection_cache = 1, i;

     if (READ_ATTRIB("HashConnectionCache") && !HashConcurrentUser)
        connection_cache = strtol(READ_ATTRIB("HashConnectionCache"), NULL, 0);

      LOGDEBUG("unloading hash database from memory");
      if (DTX->connections) {
        for(i=0;i<connection_cache;i++) {
          LOGDEBUG("unloading connection object %d", i);
          if (DTX->connections[i]) {
            if (!HashConcurrentUser) {
              pthread_mutex_destroy(&DTX->connections[i]->lock);
            }
            else {
              pthread_rwlock_destroy(&DTX->connections[i]->rwlock);
              map = (hash_drv_map_t) DTX->connections[i]->dbh;
              if (map)
                _hash_drv_close(map);
            }
            free(DTX->connections[i]->dbh);
            free(DTX->connections[i]);
          }
        }
        free(DTX->connections);
      }
    }
  }
#endif

  return 0;
}
Exemplo n.º 5
0
int cssstat(const char *filename) {
  struct _hash_drv_map map;
  hash_drv_header_t header;
  hash_drv_spam_record_t rec;
  unsigned long filepos = sizeof(struct _hash_drv_header);
  unsigned long nfree = 0, nused = 0;
  unsigned long efree, eused;
  unsigned long extents = 0;
  unsigned long i;

  unsigned long hash_rec_max = HASH_REC_MAX;
  unsigned long max_seek     = HASH_SEEK_MAX;
  unsigned long max_extents  = 0;
  unsigned long extent_size  = HASH_EXTENT_MAX;
  int flags = 0;

  if (READ_ATTRIB("HashRecMax"))
    hash_rec_max = strtol(READ_ATTRIB("HashRecMax"), NULL, 0);

  if (READ_ATTRIB("HashExtentSize"))
    extent_size = strtol(READ_ATTRIB("HashExtentSize"), NULL, 0);

  if (READ_ATTRIB("HashMaxExtents"))
    max_extents = strtol(READ_ATTRIB("HashMaxExtents"), NULL, 0);

  if (MATCH_ATTRIB("HashAutoExtend", "on"))
    flags = HMAP_AUTOEXTEND;

  if (READ_ATTRIB("HashMaxSeek"))
     max_seek = strtol(READ_ATTRIB("HashMaxSeek"), NULL, 0);

  if (_hash_drv_open(filename, &map, 0, max_seek, 
                     max_extents, extent_size, 0, flags))
  {
    return EFAILURE;
  }

  header = map.addr;
  printf("filename %s length %ld\n", filename, (long) map.file_len);

  while(filepos < map.file_len) {
    printf("extent %lu: record length %lu\n", extents, 
      (unsigned long) header->hash_rec_max);
    efree = eused = 0;
    for(i=0;i<header->hash_rec_max;i++) {
      rec = map.addr+filepos;
      if (rec->hashcode) {
        eused++; 
        nused++;
      } else {
        efree++;
        nfree++;
      }
      filepos += sizeof(struct _hash_drv_spam_record);
    }
    header = map.addr + filepos;
    filepos += sizeof(struct _hash_drv_header);
    extents++;

    printf("\textent records used %lu\n", eused);
    printf("\textent records free %lu\n", efree);
  }

  _hash_drv_close(&map);

  printf("total database records used %lu\n", nused);
  printf("total database records free %lu\n", nfree);
  printf("total extents               %lu\n", extents);
  return 0;
}
Exemplo n.º 6
0
int
_ds_init_storage (DSPAM_CTX * CTX, void *dbh)
{
  struct _hash_drv_storage *s = NULL;
  hash_drv_map_t map = NULL;
  int ret;

  if (CTX == NULL)
    return EINVAL;

  if (!CTX->home) {
    LOG(LOG_ERR, ERR_AGENT_DSPAM_HOME);
    return EINVAL;
  }

  if (CTX->flags & DSF_MERGED) {
    LOG(LOG_ERR, ERR_DRV_NO_MERGED);
    return EINVAL;
  }

  if (CTX->storage)
    return EINVAL;

  /* Persistent driver storage */

  s = calloc (1, sizeof (struct _hash_drv_storage));
  if (s == NULL)
  {
    LOG(LOG_CRIT, ERR_MEM_ALLOC);
    return EUNKNOWN;
  }

  /* If running in HashConcurrentUser mode, use existing hash mapping */

  if (dbh) {
    map = dbh;
    s->dbh_attached = 1;
  } else {
    map = calloc(1, sizeof(struct _hash_drv_map));
    if (!map) {
      LOG(LOG_CRIT, ERR_MEM_ALLOC);
      free(s);
      return EUNKNOWN;
    }
    s->dbh_attached = 0;
  }

  s->map = map;

  /* Mapping defaults */

  s->hash_rec_max = HASH_REC_MAX;
  s->max_seek     = HASH_SEEK_MAX;
  s->max_extents  = 0;
  s->extent_size  = HASH_EXTENT_MAX;
  s->pctincrease  = 0;
  s->flags        = HMAP_AUTOEXTEND;

  if (READ_ATTRIB("HashRecMax"))
    s->hash_rec_max = strtol(READ_ATTRIB("HashRecMax"), NULL, 0);

  if (READ_ATTRIB("HashExtentSize"))
    s->extent_size = strtol(READ_ATTRIB("HashExtentSize"), NULL, 0);

  if (READ_ATTRIB("HashMaxExtents"))
    s->max_extents = strtol(READ_ATTRIB("HashMaxExtents"), NULL, 0);

  if (!MATCH_ATTRIB("HashAutoExtend", "on"))
    s->flags = 0;

  if (READ_ATTRIB("HashPctIncrease")) {
    s->pctincrease = atoi(READ_ATTRIB("HashPctIncrease"));
    if (s->pctincrease > 100) {
        LOG(LOG_ERR, "HashPctIncrease out of range; ignoring");
        s->pctincrease = 0;
    }
  }

  if (READ_ATTRIB("HashMaxSeek"))
    s->max_seek = strtol(READ_ATTRIB("HashMaxSeek"), NULL, 0);

  if (!dbh && CTX->username != NULL)
  {
    char db[MAX_FILENAME_LENGTH];
    int lock_result;

    if (CTX->group == NULL)
      _ds_userdir_path(db, CTX->home, CTX->username, "css");
    else
      _ds_userdir_path(db, CTX->home, CTX->group, "css");

    lock_result = _hash_drv_lock_get (CTX, s, 
      (CTX->group) ? CTX->group : CTX->username);
    if (lock_result < 0) 
      goto BAIL;

    ret = _hash_drv_open(db, s->map, s->hash_rec_max, s->max_seek, 
        s->max_extents, s->extent_size, s->pctincrease, s->flags);

    if (ret) {
      _hash_drv_close(s->map);
      free(s);
      return EFAILURE;
    }
  }

  CTX->storage = s;
  s->dir_handles = nt_create (NT_INDEX);

  if (_hash_drv_get_spamtotals (CTX))
  {
    LOGDEBUG ("unable to load totals.  using zero values.");
    memset (&CTX->totals, 0, sizeof (struct _ds_spam_totals));
  }

  return 0;

BAIL:
  free(s);
  return EFAILURE;
}