mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
549 lines
9.3 KiB
549 lines
9.3 KiB
/*
|
|
* $Id$
|
|
*
|
|
* DBText library
|
|
*
|
|
* Copyright (C) 2001-2003 FhG Fokus
|
|
*
|
|
* This file is part of ser, a free SIP server.
|
|
*
|
|
* ser is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version
|
|
*
|
|
* For a license to use the ser software under conditions
|
|
* other than those described here, or to purchase support for this
|
|
* software, please contact iptel.org by e-mail at the following addresses:
|
|
* info@iptel.org
|
|
*
|
|
* ser is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
/**
|
|
* DBText library
|
|
*
|
|
* 2003-01-30 created by Daniel
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
|
|
#include "../../mem/shm_mem.h"
|
|
#include "../../mem/mem.h"
|
|
#include "../../dprint.h"
|
|
|
|
#include "dbt_util.h"
|
|
#include "dbt_lib.h"
|
|
|
|
static dbt_cache_p *_cachedb = NULL;
|
|
static gen_lock_t *_cachesem = NULL;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int dbt_init_cache()
|
|
{
|
|
if(!_cachesem)
|
|
{
|
|
/* init locks */
|
|
_cachesem = lock_alloc();
|
|
if(!_cachesem)
|
|
{
|
|
LOG(L_CRIT,"dbtext:dbt_init_cache: could not alloc a lock\n");
|
|
return -1;
|
|
}
|
|
if (lock_init(_cachesem)==0)
|
|
{
|
|
LOG(L_CRIT,"dbtext:dbt_init_cache: could not initialize a lock\n");
|
|
lock_dealloc(_cachesem);
|
|
return -1;
|
|
}
|
|
}
|
|
/* init pointer to caches list */
|
|
if (!_cachedb) {
|
|
_cachedb = shm_malloc( sizeof(dbt_cache_p) );
|
|
if (!_cachedb) {
|
|
LOG(L_CRIT,"dbtext:dbt_init_cache: no enough shm mem\n");
|
|
lock_dealloc(_cachesem);
|
|
return -1;
|
|
}
|
|
*_cachedb = NULL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
dbt_cache_p dbt_cache_get_db(str *_s)
|
|
{
|
|
dbt_cache_p _dcache=NULL;;
|
|
if(!_cachesem || !_cachedb)
|
|
{
|
|
LOG(L_ERR, "DBT:dbt_cache_get_db:dbtext cache is not initialized!\n");
|
|
return NULL;
|
|
}
|
|
if(!_s || !_s->s || _s->len<=0)
|
|
return NULL;
|
|
|
|
DBG("DBT:dbt_cache_get_db: looking for db %.*s!\n",_s->len,_s->s);
|
|
|
|
lock_get(_cachesem);
|
|
|
|
_dcache = *_cachedb;
|
|
while(_dcache)
|
|
{
|
|
lock_get(&_dcache->sem);
|
|
if(_dcache->dbp)
|
|
{
|
|
if(_dcache->dbp->name.len==_s->len
|
|
&& !strncasecmp(_dcache->dbp->name.s, _s->s, _s->len))
|
|
{
|
|
lock_release(&_dcache->sem);
|
|
DBG("DBT:dbt_cache_get_db: db already cached!\n");
|
|
goto done;
|
|
}
|
|
}
|
|
lock_release(&_dcache->sem);
|
|
|
|
_dcache = _dcache->next;
|
|
}
|
|
if(!dbt_is_database(_s))
|
|
{
|
|
LOG(L_ERR, "DBT:dbt_cache_get_db: database [%.*s] does not exists!\n",
|
|
_s->len, _s->s);
|
|
goto done;
|
|
}
|
|
DBG("DBT:dbt_cache_get_db: new db!\n");
|
|
|
|
_dcache = (dbt_cache_p)shm_malloc(sizeof(dbt_cache_t));
|
|
if(!_dcache)
|
|
{
|
|
LOG(L_ERR, "DBT:dbt_cache_get_db: no memory for dbt_cache_t.\n");
|
|
goto done;
|
|
}
|
|
|
|
_dcache->dbp = (dbt_db_p)shm_malloc(sizeof(dbt_db_t));
|
|
if(!_dcache->dbp)
|
|
{
|
|
LOG(L_ERR, "DBT:dbt_cache_get_db: no memory for dbt_db_t!\n");
|
|
shm_free(_dcache);
|
|
goto done;
|
|
}
|
|
|
|
_dcache->dbp->name.s = (char*)shm_malloc(_s->len*sizeof(char));
|
|
if(!_dcache->dbp->name.s)
|
|
{
|
|
LOG(L_ERR, "DBT:dbt_cache_get_db: no memory for s!!\n");
|
|
shm_free(_dcache->dbp);
|
|
shm_free(_dcache);
|
|
_dcache = NULL;
|
|
goto done;
|
|
}
|
|
|
|
memcpy(_dcache->dbp->name.s, _s->s, _s->len);
|
|
_dcache->dbp->name.len = _s->len;
|
|
_dcache->dbp->tables = NULL;
|
|
|
|
if(!lock_init(&_dcache->sem))
|
|
{
|
|
LOG(L_ERR, "DBT:dbt_cache_get_db: no sems!\n");
|
|
shm_free(_dcache->dbp->name.s);
|
|
shm_free(_dcache->dbp);
|
|
shm_free(_dcache);
|
|
_dcache = NULL;
|
|
goto done;
|
|
}
|
|
|
|
_dcache->prev = NULL;
|
|
|
|
if(*_cachedb)
|
|
{
|
|
_dcache->next = *_cachedb;
|
|
(*_cachedb)->prev = _dcache;
|
|
}
|
|
else
|
|
_dcache->next = NULL;
|
|
|
|
*_cachedb = _dcache;
|
|
|
|
done:
|
|
lock_release(_cachesem);
|
|
return _dcache;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int dbt_cache_check_db(str *_s)
|
|
{
|
|
dbt_cache_p _dcache=NULL;;
|
|
if(!_cachesem || !(*_cachedb) || !_s || !_s->s || _s->len<=0)
|
|
return -1;
|
|
|
|
lock_get(_cachesem);
|
|
|
|
_dcache = *_cachedb;
|
|
while(_dcache)
|
|
{
|
|
if(_dcache->dbp)
|
|
{
|
|
if(_dcache->dbp->name.len == _s->len &&
|
|
strncasecmp(_dcache->dbp->name.s, _s->s, _s->len))
|
|
{
|
|
lock_release(_cachesem);
|
|
return 0;
|
|
}
|
|
}
|
|
_dcache = _dcache->next;
|
|
}
|
|
|
|
lock_release(_cachesem);
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int dbt_cache_del_db(str *_s)
|
|
{
|
|
dbt_cache_p _dcache=NULL;;
|
|
if(!_cachesem || !(*_cachedb) || !_s || !_s->s || _s->len<=0)
|
|
return -1;
|
|
|
|
lock_get(_cachesem);
|
|
|
|
_dcache = *_cachedb;
|
|
while(_dcache)
|
|
{
|
|
if(_dcache->dbp)
|
|
{
|
|
if(_dcache->dbp->name.len == _s->len
|
|
&& strncasecmp(_dcache->dbp->name.s, _s->s, _s->len))
|
|
break;
|
|
}
|
|
// else - delete this cell
|
|
_dcache = _dcache->next;
|
|
}
|
|
if(!_dcache)
|
|
{
|
|
lock_release(_cachesem);
|
|
return 0;
|
|
}
|
|
|
|
if(_dcache->prev)
|
|
(_dcache->prev)->next = _dcache->next;
|
|
else
|
|
*_cachedb = _dcache->next;
|
|
|
|
if(_dcache->next)
|
|
(_dcache->next)->prev = _dcache->prev;
|
|
|
|
lock_release(_cachesem);
|
|
|
|
dbt_cache_free(_dcache);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
tbl_cache_p dbt_db_get_table(dbt_cache_p _dc, str *_s)
|
|
{
|
|
// dbt_db_p _dbp = NULL;
|
|
tbl_cache_p _tbc = NULL;
|
|
dbt_table_p _dtp = NULL;
|
|
|
|
if(!_dc || !_s || !_s->s || _s->len<=0)
|
|
return NULL;
|
|
|
|
lock_get(&_dc->sem);
|
|
if(!_dc->dbp)
|
|
{
|
|
lock_release(&_dc->sem);
|
|
return NULL;
|
|
}
|
|
|
|
_tbc = _dc->dbp->tables;
|
|
while(_tbc)
|
|
{
|
|
if(_tbc->dtp)
|
|
{
|
|
lock_get(&_tbc->sem);
|
|
if(_tbc->dtp->name.len == _s->len
|
|
&& !strncasecmp(_tbc->dtp->name.s, _s->s, _s->len ))
|
|
{
|
|
lock_release(&_tbc->sem);
|
|
lock_release(&_dc->sem);
|
|
return _tbc;
|
|
}
|
|
lock_release(&_tbc->sem);
|
|
}
|
|
_tbc = _tbc->next;
|
|
}
|
|
|
|
// new table
|
|
_tbc = tbl_cache_new();
|
|
if(!_tbc)
|
|
{
|
|
lock_release(&_dc->sem);
|
|
return NULL;
|
|
}
|
|
|
|
_dtp = dbt_load_file(_s, &(_dc->dbp->name));
|
|
|
|
#ifdef DBT_EXTRA_DEBUG
|
|
DBG("DTB:dbt_db_get_table: %.*s\n", _s->len, _s->s);
|
|
dbt_print_table(_dtp, NULL);
|
|
#endif
|
|
|
|
if(!_dtp)
|
|
{
|
|
lock_release(&_dc->sem);
|
|
return NULL;
|
|
}
|
|
_tbc->dtp = _dtp;
|
|
|
|
if(_dc->dbp->tables)
|
|
(_dc->dbp->tables)->prev = _tbc;
|
|
_tbc->next = _dc->dbp->tables;
|
|
_dc->dbp->tables = _tbc;
|
|
|
|
lock_release(&_dc->sem);
|
|
|
|
return _tbc;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int dbt_db_del_table(dbt_cache_p _dc, str *_s)
|
|
{
|
|
tbl_cache_p _tbc = NULL;
|
|
if(!_dc || !_s || !_s->s || _s->len<=0)
|
|
return -1;
|
|
|
|
lock_get(&_dc->sem);
|
|
if(!_dc->dbp)
|
|
{
|
|
lock_release(&_dc->sem);
|
|
return -1;
|
|
}
|
|
|
|
_tbc = _dc->dbp->tables;
|
|
while(_tbc)
|
|
{
|
|
if(_tbc->dtp)
|
|
{
|
|
lock_get(&_tbc->sem);
|
|
if(_tbc->dtp->name.len == _s->len
|
|
&& !strncasecmp(_tbc->dtp->name.s, _s->s, _s->len))
|
|
{
|
|
if(_tbc->prev)
|
|
(_tbc->prev)->next = _tbc->next;
|
|
else
|
|
_dc->dbp->tables = _tbc->next;
|
|
|
|
if(_tbc->next)
|
|
(_tbc->next)->prev = _tbc->prev;
|
|
break;
|
|
}
|
|
lock_release(&_tbc->sem);
|
|
}
|
|
_tbc = _tbc->next;
|
|
}
|
|
|
|
lock_release(&_dc->sem);
|
|
|
|
tbl_cache_free(_tbc);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int dbt_cache_destroy()
|
|
{
|
|
dbt_cache_p _dc=NULL, _dc0=NULL;
|
|
|
|
if(!_cachesem)
|
|
return -1;
|
|
|
|
lock_get(_cachesem);
|
|
if( _cachedb!=NULL )
|
|
{
|
|
_dc = *_cachedb;
|
|
while(_dc)
|
|
{
|
|
_dc0 = _dc;
|
|
_dc = _dc->next;
|
|
dbt_cache_free(_dc0);
|
|
}
|
|
shm_free(_cachedb);
|
|
}
|
|
lock_destroy(_cachesem);
|
|
lock_dealloc(_cachesem);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int dbt_cache_print(int _f)
|
|
{
|
|
dbt_cache_p _dc=NULL;
|
|
tbl_cache_p _tbc = NULL;
|
|
|
|
if(!_cachesem)
|
|
return -1;
|
|
|
|
lock_get(_cachesem);
|
|
|
|
_dc = *_cachedb;
|
|
while(_dc)
|
|
{
|
|
lock_get(&_dc->sem);
|
|
if(_dc->dbp)
|
|
{
|
|
if(_f)
|
|
fprintf(stdout, "\n--- Database [%.*s]\n", _dc->dbp->name.len,
|
|
_dc->dbp->name.s);
|
|
|
|
_tbc = _dc->dbp->tables;
|
|
while(_tbc)
|
|
{
|
|
lock_get(&_tbc->sem);
|
|
if(_tbc->dtp)
|
|
{
|
|
if(_f)
|
|
{
|
|
fprintf(stdout, "\n----- Table [%.*s]\n",
|
|
_tbc->dtp->name.len, _tbc->dtp->name.s);
|
|
fprintf(stdout, "------- LA=<%d> FL=<%x> AC=<%d>"
|
|
" AV=<%d>\n", _tbc->dtp->mark, _tbc->dtp->flag,
|
|
_tbc->dtp->auto_col, _tbc->dtp->auto_val);
|
|
dbt_print_table(_tbc->dtp, NULL);
|
|
}
|
|
else
|
|
{
|
|
if(_tbc->dtp->flag & DBT_TBFL_MODI)
|
|
{
|
|
dbt_print_table(_tbc->dtp, &(_dc->dbp->name));
|
|
dbt_table_update_flags(_tbc->dtp,DBT_TBFL_MODI,
|
|
DBT_FL_UNSET, 0);
|
|
}
|
|
}
|
|
}
|
|
lock_release(&_tbc->sem);
|
|
_tbc = _tbc->next;
|
|
}
|
|
}
|
|
lock_release(&_dc->sem);
|
|
|
|
_dc = _dc->next;
|
|
}
|
|
|
|
lock_release(_cachesem);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int dbt_cache_free(dbt_cache_p _dc)
|
|
{
|
|
if(!_dc)
|
|
return -1;
|
|
|
|
lock_get(&_dc->sem);
|
|
|
|
if(_dc->dbp)
|
|
dbt_db_free(_dc->dbp);
|
|
|
|
lock_destroy(&_dc->sem);
|
|
|
|
shm_free(_dc);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int dbt_db_free(dbt_db_p _dbp)
|
|
{
|
|
tbl_cache_p _tbc = NULL, _tbc0=NULL;
|
|
if(!_dbp)
|
|
return -1;
|
|
|
|
_tbc = _dbp->tables;
|
|
|
|
while(_tbc)
|
|
{
|
|
_tbc0 = _tbc;
|
|
tbl_cache_free(_tbc0);
|
|
_tbc = _tbc->next;
|
|
}
|
|
|
|
if(_dbp->name.s)
|
|
shm_free(_dbp->name.s);
|
|
|
|
shm_free(_dbp);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
tbl_cache_p tbl_cache_new()
|
|
{
|
|
tbl_cache_p _tbc = NULL;
|
|
_tbc = (tbl_cache_p)shm_malloc(sizeof(tbl_cache_t));
|
|
if(!_tbc)
|
|
return NULL;
|
|
if(!lock_init(&_tbc->sem))
|
|
{
|
|
shm_free(_tbc);
|
|
return NULL;
|
|
}
|
|
return _tbc;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
int tbl_cache_free(tbl_cache_p _tbc)
|
|
{
|
|
// FILL IT IN ?????????????
|
|
if(!_tbc)
|
|
return -1;
|
|
lock_get(&_tbc->sem);
|
|
|
|
if(_tbc->dtp)
|
|
dbt_table_free(_tbc->dtp);
|
|
|
|
lock_destroy(&_tbc->sem);
|
|
shm_free(_tbc);
|
|
|
|
return 0;
|
|
}
|
|
|