dbt_lib.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. /*
  2. * $Id$
  3. *
  4. * DBText library
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  10. * ser is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * For a license to use the ser software under conditions
  16. * other than those described here, or to purchase support for this
  17. * software, please contact iptel.org by e-mail at the following addresses:
  18. * [email protected]
  19. *
  20. * ser is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. /**
  30. * DBText library
  31. *
  32. * 2003-01-30 created by Daniel
  33. *
  34. */
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <time.h>
  38. #include <sys/types.h>
  39. #include <dirent.h>
  40. #include "../../mem/shm_mem.h"
  41. #include "../../mem/mem.h"
  42. #include "../../dprint.h"
  43. #include "dbt_util.h"
  44. #include "dbt_lib.h"
  45. static dbt_cache_p *_cachedb = NULL;
  46. static gen_lock_t *_cachesem = NULL;
  47. /**
  48. *
  49. */
  50. int dbt_init_cache()
  51. {
  52. if(!_cachesem)
  53. {
  54. /* init locks */
  55. _cachesem = lock_alloc();
  56. if(!_cachesem)
  57. {
  58. LOG(L_CRIT,"dbtext:dbt_init_cache: could not alloc a lock\n");
  59. return -1;
  60. }
  61. if (lock_init(_cachesem)==0)
  62. {
  63. LOG(L_CRIT,"dbtext:dbt_init_cache: could not initialize a lock\n");
  64. lock_dealloc(_cachesem);
  65. return -1;
  66. }
  67. }
  68. /* init pointer to caches list */
  69. if (!_cachedb) {
  70. _cachedb = shm_malloc( sizeof(dbt_cache_p) );
  71. if (!_cachedb) {
  72. LOG(L_CRIT,"dbtext:dbt_init_cache: no enough shm mem\n");
  73. lock_dealloc(_cachesem);
  74. return -1;
  75. }
  76. *_cachedb = NULL;
  77. }
  78. return 0;
  79. }
  80. /**
  81. *
  82. */
  83. dbt_cache_p dbt_cache_get_db(str *_s)
  84. {
  85. dbt_cache_p _dcache=NULL;;
  86. if(!_cachesem || !_cachedb)
  87. {
  88. LOG(L_ERR, "DBT:dbt_cache_get_db:dbtext cache is not initialized!\n");
  89. return NULL;
  90. }
  91. if(!_s || !_s->s || _s->len<=0)
  92. return NULL;
  93. DBG("DBT:dbt_cache_get_db: looking for db %.*s!\n",_s->len,_s->s);
  94. lock_get(_cachesem);
  95. _dcache = *_cachedb;
  96. while(_dcache)
  97. {
  98. lock_get(&_dcache->sem);
  99. if(_dcache->dbp)
  100. {
  101. if(_dcache->dbp->name.len==_s->len
  102. && !strncasecmp(_dcache->dbp->name.s, _s->s, _s->len))
  103. {
  104. lock_release(&_dcache->sem);
  105. DBG("DBT:dbt_cache_get_db: db already cached!\n");
  106. goto done;
  107. }
  108. }
  109. lock_release(&_dcache->sem);
  110. _dcache = _dcache->next;
  111. }
  112. if(!dbt_is_database(_s))
  113. {
  114. LOG(L_ERR, "DBT:dbt_cache_get_db: database [%.*s] does not exists!\n",
  115. _s->len, _s->s);
  116. goto done;
  117. }
  118. DBG("DBT:dbt_cache_get_db: new db!\n");
  119. _dcache = (dbt_cache_p)shm_malloc(sizeof(dbt_cache_t));
  120. if(!_dcache)
  121. {
  122. LOG(L_ERR, "DBT:dbt_cache_get_db: no memory for dbt_cache_t.\n");
  123. goto done;
  124. }
  125. _dcache->dbp = (dbt_db_p)shm_malloc(sizeof(dbt_db_t));
  126. if(!_dcache->dbp)
  127. {
  128. LOG(L_ERR, "DBT:dbt_cache_get_db: no memory for dbt_db_t!\n");
  129. shm_free(_dcache);
  130. goto done;
  131. }
  132. _dcache->dbp->name.s = (char*)shm_malloc(_s->len*sizeof(char));
  133. if(!_dcache->dbp->name.s)
  134. {
  135. LOG(L_ERR, "DBT:dbt_cache_get_db: no memory for s!!\n");
  136. shm_free(_dcache->dbp);
  137. shm_free(_dcache);
  138. _dcache = NULL;
  139. goto done;
  140. }
  141. memcpy(_dcache->dbp->name.s, _s->s, _s->len);
  142. _dcache->dbp->name.len = _s->len;
  143. _dcache->dbp->tables = NULL;
  144. if(!lock_init(&_dcache->sem))
  145. {
  146. LOG(L_ERR, "DBT:dbt_cache_get_db: no sems!\n");
  147. shm_free(_dcache->dbp->name.s);
  148. shm_free(_dcache->dbp);
  149. shm_free(_dcache);
  150. _dcache = NULL;
  151. goto done;
  152. }
  153. _dcache->prev = NULL;
  154. if(*_cachedb)
  155. {
  156. _dcache->next = *_cachedb;
  157. (*_cachedb)->prev = _dcache;
  158. }
  159. else
  160. _dcache->next = NULL;
  161. *_cachedb = _dcache;
  162. done:
  163. lock_release(_cachesem);
  164. return _dcache;
  165. }
  166. /**
  167. *
  168. */
  169. int dbt_cache_check_db(str *_s)
  170. {
  171. dbt_cache_p _dcache=NULL;;
  172. if(!_cachesem || !(*_cachedb) || !_s || !_s->s || _s->len<=0)
  173. return -1;
  174. lock_get(_cachesem);
  175. _dcache = *_cachedb;
  176. while(_dcache)
  177. {
  178. if(_dcache->dbp)
  179. {
  180. if(_dcache->dbp->name.len == _s->len &&
  181. strncasecmp(_dcache->dbp->name.s, _s->s, _s->len))
  182. {
  183. lock_release(_cachesem);
  184. return 0;
  185. }
  186. }
  187. _dcache = _dcache->next;
  188. }
  189. lock_release(_cachesem);
  190. return -1;
  191. }
  192. /**
  193. *
  194. */
  195. int dbt_cache_del_db(str *_s)
  196. {
  197. dbt_cache_p _dcache=NULL;;
  198. if(!_cachesem || !(*_cachedb) || !_s || !_s->s || _s->len<=0)
  199. return -1;
  200. lock_get(_cachesem);
  201. _dcache = *_cachedb;
  202. while(_dcache)
  203. {
  204. if(_dcache->dbp)
  205. {
  206. if(_dcache->dbp->name.len == _s->len
  207. && strncasecmp(_dcache->dbp->name.s, _s->s, _s->len))
  208. break;
  209. }
  210. // else - delete this cell
  211. _dcache = _dcache->next;
  212. }
  213. if(!_dcache)
  214. {
  215. lock_release(_cachesem);
  216. return 0;
  217. }
  218. if(_dcache->prev)
  219. (_dcache->prev)->next = _dcache->next;
  220. else
  221. *_cachedb = _dcache->next;
  222. if(_dcache->next)
  223. (_dcache->next)->prev = _dcache->prev;
  224. lock_release(_cachesem);
  225. dbt_cache_free(_dcache);
  226. return 0;
  227. }
  228. /**
  229. *
  230. */
  231. tbl_cache_p dbt_db_get_table(dbt_cache_p _dc, str *_s)
  232. {
  233. // dbt_db_p _dbp = NULL;
  234. tbl_cache_p _tbc = NULL;
  235. dbt_table_p _dtp = NULL;
  236. if(!_dc || !_s || !_s->s || _s->len<=0)
  237. return NULL;
  238. lock_get(&_dc->sem);
  239. if(!_dc->dbp)
  240. {
  241. lock_release(&_dc->sem);
  242. return NULL;
  243. }
  244. _tbc = _dc->dbp->tables;
  245. while(_tbc)
  246. {
  247. if(_tbc->dtp)
  248. {
  249. lock_get(&_tbc->sem);
  250. if(_tbc->dtp->name.len == _s->len
  251. && !strncasecmp(_tbc->dtp->name.s, _s->s, _s->len ))
  252. {
  253. lock_release(&_tbc->sem);
  254. lock_release(&_dc->sem);
  255. return _tbc;
  256. }
  257. lock_release(&_tbc->sem);
  258. }
  259. _tbc = _tbc->next;
  260. }
  261. // new table
  262. _tbc = tbl_cache_new();
  263. if(!_tbc)
  264. {
  265. lock_release(&_dc->sem);
  266. return NULL;
  267. }
  268. _dtp = dbt_load_file(_s, &(_dc->dbp->name));
  269. #ifdef DBT_EXTRA_DEBUG
  270. DBG("DTB:dbt_db_get_table: %.*s\n", _s->len, _s->s);
  271. dbt_print_table(_dtp, NULL);
  272. #endif
  273. if(!_dtp)
  274. {
  275. lock_release(&_dc->sem);
  276. return NULL;
  277. }
  278. _tbc->dtp = _dtp;
  279. if(_dc->dbp->tables)
  280. (_dc->dbp->tables)->prev = _tbc;
  281. _tbc->next = _dc->dbp->tables;
  282. _dc->dbp->tables = _tbc;
  283. lock_release(&_dc->sem);
  284. return _tbc;
  285. }
  286. /**
  287. *
  288. */
  289. int dbt_db_del_table(dbt_cache_p _dc, str *_s)
  290. {
  291. tbl_cache_p _tbc = NULL;
  292. if(!_dc || !_s || !_s->s || _s->len<=0)
  293. return -1;
  294. lock_get(&_dc->sem);
  295. if(!_dc->dbp)
  296. {
  297. lock_release(&_dc->sem);
  298. return -1;
  299. }
  300. _tbc = _dc->dbp->tables;
  301. while(_tbc)
  302. {
  303. if(_tbc->dtp)
  304. {
  305. lock_get(&_tbc->sem);
  306. if(_tbc->dtp->name.len == _s->len
  307. && !strncasecmp(_tbc->dtp->name.s, _s->s, _s->len))
  308. {
  309. if(_tbc->prev)
  310. (_tbc->prev)->next = _tbc->next;
  311. else
  312. _dc->dbp->tables = _tbc->next;
  313. if(_tbc->next)
  314. (_tbc->next)->prev = _tbc->prev;
  315. break;
  316. }
  317. lock_release(&_tbc->sem);
  318. }
  319. _tbc = _tbc->next;
  320. }
  321. lock_release(&_dc->sem);
  322. tbl_cache_free(_tbc);
  323. return 0;
  324. }
  325. /**
  326. *
  327. */
  328. int dbt_cache_destroy()
  329. {
  330. dbt_cache_p _dc=NULL, _dc0=NULL;
  331. if(!_cachesem)
  332. return -1;
  333. lock_get(_cachesem);
  334. if( _cachedb!=NULL )
  335. {
  336. _dc = *_cachedb;
  337. while(_dc)
  338. {
  339. _dc0 = _dc;
  340. _dc = _dc->next;
  341. dbt_cache_free(_dc0);
  342. }
  343. shm_free(_cachedb);
  344. }
  345. lock_destroy(_cachesem);
  346. lock_dealloc(_cachesem);
  347. return 0;
  348. }
  349. /**
  350. *
  351. */
  352. int dbt_cache_print(int _f)
  353. {
  354. dbt_cache_p _dc=NULL;
  355. tbl_cache_p _tbc = NULL;
  356. if(!_cachesem)
  357. return -1;
  358. lock_get(_cachesem);
  359. _dc = *_cachedb;
  360. while(_dc)
  361. {
  362. lock_get(&_dc->sem);
  363. if(_dc->dbp)
  364. {
  365. if(_f)
  366. fprintf(stdout, "\n--- Database [%.*s]\n", _dc->dbp->name.len,
  367. _dc->dbp->name.s);
  368. _tbc = _dc->dbp->tables;
  369. while(_tbc)
  370. {
  371. lock_get(&_tbc->sem);
  372. if(_tbc->dtp)
  373. {
  374. if(_f)
  375. {
  376. fprintf(stdout, "\n----- Table [%.*s]\n",
  377. _tbc->dtp->name.len, _tbc->dtp->name.s);
  378. fprintf(stdout, "------- LA=<%d> FL=<%x> AC=<%d>"
  379. " AV=<%d>\n", _tbc->dtp->mark, _tbc->dtp->flag,
  380. _tbc->dtp->auto_col, _tbc->dtp->auto_val);
  381. dbt_print_table(_tbc->dtp, NULL);
  382. }
  383. else
  384. {
  385. if(_tbc->dtp->flag & DBT_TBFL_MODI)
  386. {
  387. dbt_print_table(_tbc->dtp, &(_dc->dbp->name));
  388. dbt_table_update_flags(_tbc->dtp,DBT_TBFL_MODI,
  389. DBT_FL_UNSET, 0);
  390. }
  391. }
  392. }
  393. lock_release(&_tbc->sem);
  394. _tbc = _tbc->next;
  395. }
  396. }
  397. lock_release(&_dc->sem);
  398. _dc = _dc->next;
  399. }
  400. lock_release(_cachesem);
  401. return 0;
  402. }
  403. /**
  404. *
  405. */
  406. int dbt_cache_free(dbt_cache_p _dc)
  407. {
  408. if(!_dc)
  409. return -1;
  410. lock_get(&_dc->sem);
  411. if(_dc->dbp)
  412. dbt_db_free(_dc->dbp);
  413. lock_destroy(&_dc->sem);
  414. shm_free(_dc);
  415. return 0;
  416. }
  417. /**
  418. *
  419. */
  420. int dbt_db_free(dbt_db_p _dbp)
  421. {
  422. tbl_cache_p _tbc = NULL, _tbc0=NULL;
  423. if(!_dbp)
  424. return -1;
  425. _tbc = _dbp->tables;
  426. while(_tbc)
  427. {
  428. _tbc0 = _tbc;
  429. tbl_cache_free(_tbc0);
  430. _tbc = _tbc->next;
  431. }
  432. if(_dbp->name.s)
  433. shm_free(_dbp->name.s);
  434. shm_free(_dbp);
  435. return 0;
  436. }
  437. /**
  438. *
  439. */
  440. tbl_cache_p tbl_cache_new()
  441. {
  442. tbl_cache_p _tbc = NULL;
  443. _tbc = (tbl_cache_p)shm_malloc(sizeof(tbl_cache_t));
  444. if(!_tbc)
  445. return NULL;
  446. if(!lock_init(&_tbc->sem))
  447. {
  448. shm_free(_tbc);
  449. return NULL;
  450. }
  451. return _tbc;
  452. }
  453. /**
  454. *
  455. */
  456. int tbl_cache_free(tbl_cache_p _tbc)
  457. {
  458. // FILL IT IN ?????????????
  459. if(!_tbc)
  460. return -1;
  461. lock_get(&_tbc->sem);
  462. if(_tbc->dtp)
  463. dbt_table_free(_tbc->dtp);
  464. lock_destroy(&_tbc->sem);
  465. shm_free(_tbc);
  466. return 0;
  467. }