ntdbtool.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. /*
  2. Unix SMB/CIFS implementation.
  3. Samba database functions
  4. Copyright (C) Andrew Tridgell 1999-2000
  5. Copyright (C) Paul `Rusty' Russell 2000
  6. Copyright (C) Jeremy Allison 2000
  7. Copyright (C) Andrew Esh 2001
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 3 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "config.h"
  20. #include "ntdb.h"
  21. #include "private.h"
  22. static int do_command(void);
  23. const char *cmdname;
  24. char *arg1, *arg2;
  25. size_t arg1len, arg2len;
  26. int bIterate = 0;
  27. char *line;
  28. NTDB_DATA iterate_kbuf;
  29. char cmdline[1024];
  30. static int disable_mmap;
  31. enum commands {
  32. CMD_CREATE_NTDB,
  33. CMD_OPEN_NTDB,
  34. CMD_TRANSACTION_START,
  35. CMD_TRANSACTION_COMMIT,
  36. CMD_TRANSACTION_CANCEL,
  37. CMD_ERASE,
  38. CMD_DUMP,
  39. CMD_INSERT,
  40. CMD_MOVE,
  41. CMD_STORE,
  42. CMD_SHOW,
  43. CMD_KEYS,
  44. CMD_HEXKEYS,
  45. CMD_DELETE,
  46. #if 0
  47. CMD_LIST_HASH_FREE,
  48. CMD_LIST_FREE,
  49. #endif
  50. CMD_INFO,
  51. CMD_MMAP,
  52. CMD_SPEED,
  53. CMD_FIRST,
  54. CMD_NEXT,
  55. CMD_SYSTEM,
  56. CMD_CHECK,
  57. CMD_QUIT,
  58. CMD_HELP
  59. };
  60. typedef struct {
  61. const char *name;
  62. enum commands cmd;
  63. } COMMAND_TABLE;
  64. COMMAND_TABLE cmd_table[] = {
  65. {"create", CMD_CREATE_NTDB},
  66. {"open", CMD_OPEN_NTDB},
  67. #if 0
  68. {"transaction_start", CMD_TRANSACTION_START},
  69. {"transaction_commit", CMD_TRANSACTION_COMMIT},
  70. {"transaction_cancel", CMD_TRANSACTION_CANCEL},
  71. #endif
  72. {"erase", CMD_ERASE},
  73. {"dump", CMD_DUMP},
  74. {"insert", CMD_INSERT},
  75. {"move", CMD_MOVE},
  76. {"store", CMD_STORE},
  77. {"show", CMD_SHOW},
  78. {"keys", CMD_KEYS},
  79. {"hexkeys", CMD_HEXKEYS},
  80. {"delete", CMD_DELETE},
  81. #if 0
  82. {"list", CMD_LIST_HASH_FREE},
  83. {"free", CMD_LIST_FREE},
  84. #endif
  85. {"info", CMD_INFO},
  86. {"speed", CMD_SPEED},
  87. {"mmap", CMD_MMAP},
  88. {"first", CMD_FIRST},
  89. {"1", CMD_FIRST},
  90. {"next", CMD_NEXT},
  91. {"n", CMD_NEXT},
  92. {"check", CMD_CHECK},
  93. {"quit", CMD_QUIT},
  94. {"q", CMD_QUIT},
  95. {"!", CMD_SYSTEM},
  96. {NULL, CMD_HELP}
  97. };
  98. struct timeval tp1,tp2;
  99. static void _start_timer(void)
  100. {
  101. gettimeofday(&tp1,NULL);
  102. }
  103. static double _end_timer(void)
  104. {
  105. gettimeofday(&tp2,NULL);
  106. return((tp2.tv_sec - tp1.tv_sec) +
  107. (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
  108. }
  109. static void ntdb_log(struct ntdb_context *ntdb,
  110. enum ntdb_log_level level,
  111. enum NTDB_ERROR ecode,
  112. const char *message,
  113. void *data)
  114. {
  115. fprintf(stderr, "ntdb:%s:%s:%s\n",
  116. ntdb_name(ntdb), ntdb_errorstr(ecode), message);
  117. }
  118. /* a ntdb tool for manipulating a ntdb database */
  119. static struct ntdb_context *ntdb;
  120. static int print_rec(struct ntdb_context *the_ntdb, NTDB_DATA key, NTDB_DATA dbuf, void *state);
  121. static int print_key(struct ntdb_context *the_ntdb, NTDB_DATA key, NTDB_DATA dbuf, void *state);
  122. static int print_hexkey(struct ntdb_context *the_ntdb, NTDB_DATA key, NTDB_DATA dbuf, void *state);
  123. static void print_asc(const char *buf,int len)
  124. {
  125. int i;
  126. /* We're probably printing ASCII strings so don't try to display
  127. the trailing NULL character. */
  128. if (buf[len - 1] == 0)
  129. len--;
  130. for (i=0;i<len;i++)
  131. printf("%c",isprint(buf[i])?buf[i]:'.');
  132. }
  133. static void print_data(const char *buf,int len)
  134. {
  135. int i=0;
  136. if (len<=0) return;
  137. printf("[%03X] ",i);
  138. for (i=0;i<len;) {
  139. printf("%02X ",(int)((unsigned char)buf[i]));
  140. i++;
  141. if (i%8 == 0) printf(" ");
  142. if (i%16 == 0) {
  143. print_asc(&buf[i-16],8); printf(" ");
  144. print_asc(&buf[i-8],8); printf("\n");
  145. if (i<len) printf("[%03X] ",i);
  146. }
  147. }
  148. if (i%16) {
  149. int n;
  150. n = 16 - (i%16);
  151. printf(" ");
  152. if (n>8) printf(" ");
  153. while (n--) printf(" ");
  154. n = i%16;
  155. if (n > 8) n = 8;
  156. print_asc(&buf[i-(i%16)],n); printf(" ");
  157. n = (i%16) - n;
  158. if (n>0) print_asc(&buf[i-n],n);
  159. printf("\n");
  160. }
  161. }
  162. static void help(void)
  163. {
  164. printf("\n"
  165. "tdbtool: \n"
  166. " create dbname : create a database\n"
  167. " open dbname : open an existing database\n"
  168. " openjh dbname : open an existing database (jenkins hash)\n"
  169. " transaction_start : start a transaction\n"
  170. " transaction_commit : commit a transaction\n"
  171. " transaction_cancel : cancel a transaction\n"
  172. " erase : erase the database\n"
  173. " dump : dump the database as strings\n"
  174. " keys : dump the database keys as strings\n"
  175. " hexkeys : dump the database keys as hex values\n"
  176. " info : print summary info about the database\n"
  177. " insert key data : insert a record\n"
  178. " move key file : move a record to a destination ntdb\n"
  179. " store key data : store a record (replace)\n"
  180. " show key : show a record by key\n"
  181. " delete key : delete a record by key\n"
  182. #if 0
  183. " list : print the database hash table and freelist\n"
  184. " free : print the database freelist\n"
  185. #endif
  186. " check : check the integrity of an opened database\n"
  187. " speed : perform speed tests on the database\n"
  188. " ! command : execute system command\n"
  189. " 1 | first : print the first record\n"
  190. " n | next : print the next record\n"
  191. " q | quit : terminate\n"
  192. " \\n : repeat 'next' command\n"
  193. "\n");
  194. }
  195. static void terror(enum NTDB_ERROR err, const char *why)
  196. {
  197. if (err != NTDB_SUCCESS)
  198. printf("%s:%s\n", ntdb_errorstr(err), why);
  199. else
  200. printf("%s\n", why);
  201. }
  202. static void create_ntdb(const char *tdbname)
  203. {
  204. union ntdb_attribute log_attr;
  205. log_attr.base.attr = NTDB_ATTRIBUTE_LOG;
  206. log_attr.base.next = NULL;
  207. log_attr.log.fn = ntdb_log;
  208. if (ntdb) ntdb_close(ntdb);
  209. ntdb = ntdb_open(tdbname, (disable_mmap?NTDB_NOMMAP:0),
  210. O_RDWR | O_CREAT | O_TRUNC, 0600, &log_attr);
  211. if (!ntdb) {
  212. printf("Could not create %s: %s\n", tdbname, strerror(errno));
  213. }
  214. }
  215. static void open_ntdb(const char *tdbname)
  216. {
  217. union ntdb_attribute log_attr;
  218. log_attr.base.attr = NTDB_ATTRIBUTE_LOG;
  219. log_attr.base.next = NULL;
  220. log_attr.log.fn = ntdb_log;
  221. if (ntdb) ntdb_close(ntdb);
  222. ntdb = ntdb_open(tdbname, disable_mmap?NTDB_NOMMAP:0, O_RDWR, 0600,
  223. &log_attr);
  224. if (!ntdb) {
  225. printf("Could not open %s: %s\n", tdbname, strerror(errno));
  226. }
  227. }
  228. static void insert_ntdb(char *keyname, size_t keylen, char* data, size_t datalen)
  229. {
  230. NTDB_DATA key, dbuf;
  231. enum NTDB_ERROR ecode;
  232. if ((keyname == NULL) || (keylen == 0)) {
  233. terror(NTDB_SUCCESS, "need key");
  234. return;
  235. }
  236. key.dptr = (unsigned char *)keyname;
  237. key.dsize = keylen;
  238. dbuf.dptr = (unsigned char *)data;
  239. dbuf.dsize = datalen;
  240. ecode = ntdb_store(ntdb, key, dbuf, NTDB_INSERT);
  241. if (ecode) {
  242. terror(ecode, "insert failed");
  243. }
  244. }
  245. static void store_ntdb(char *keyname, size_t keylen, char* data, size_t datalen)
  246. {
  247. NTDB_DATA key, dbuf;
  248. enum NTDB_ERROR ecode;
  249. if ((keyname == NULL) || (keylen == 0)) {
  250. terror(NTDB_SUCCESS, "need key");
  251. return;
  252. }
  253. if ((data == NULL) || (datalen == 0)) {
  254. terror(NTDB_SUCCESS, "need data");
  255. return;
  256. }
  257. key.dptr = (unsigned char *)keyname;
  258. key.dsize = keylen;
  259. dbuf.dptr = (unsigned char *)data;
  260. dbuf.dsize = datalen;
  261. printf("Storing key:\n");
  262. print_rec(ntdb, key, dbuf, NULL);
  263. ecode = ntdb_store(ntdb, key, dbuf, NTDB_REPLACE);
  264. if (ecode) {
  265. terror(ecode, "store failed");
  266. }
  267. }
  268. static void show_ntdb(char *keyname, size_t keylen)
  269. {
  270. NTDB_DATA key, dbuf;
  271. enum NTDB_ERROR ecode;
  272. if ((keyname == NULL) || (keylen == 0)) {
  273. terror(NTDB_SUCCESS, "need key");
  274. return;
  275. }
  276. key.dptr = (unsigned char *)keyname;
  277. key.dsize = keylen;
  278. ecode = ntdb_fetch(ntdb, key, &dbuf);
  279. if (ecode) {
  280. terror(ecode, "fetch failed");
  281. return;
  282. }
  283. print_rec(ntdb, key, dbuf, NULL);
  284. free( dbuf.dptr );
  285. }
  286. static void delete_ntdb(char *keyname, size_t keylen)
  287. {
  288. NTDB_DATA key;
  289. enum NTDB_ERROR ecode;
  290. if ((keyname == NULL) || (keylen == 0)) {
  291. terror(NTDB_SUCCESS, "need key");
  292. return;
  293. }
  294. key.dptr = (unsigned char *)keyname;
  295. key.dsize = keylen;
  296. ecode = ntdb_delete(ntdb, key);
  297. if (ecode) {
  298. terror(ecode, "delete failed");
  299. }
  300. }
  301. static void move_rec(char *keyname, size_t keylen, char* tdbname)
  302. {
  303. NTDB_DATA key, dbuf;
  304. struct ntdb_context *dst_ntdb;
  305. enum NTDB_ERROR ecode;
  306. if ((keyname == NULL) || (keylen == 0)) {
  307. terror(NTDB_SUCCESS, "need key");
  308. return;
  309. }
  310. if ( !tdbname ) {
  311. terror(NTDB_SUCCESS, "need destination ntdb name");
  312. return;
  313. }
  314. key.dptr = (unsigned char *)keyname;
  315. key.dsize = keylen;
  316. ecode = ntdb_fetch(ntdb, key, &dbuf);
  317. if (ecode) {
  318. terror(ecode, "fetch failed");
  319. return;
  320. }
  321. print_rec(ntdb, key, dbuf, NULL);
  322. dst_ntdb = ntdb_open(tdbname, 0, O_RDWR, 0600, NULL);
  323. if ( !dst_ntdb ) {
  324. terror(NTDB_SUCCESS, "unable to open destination ntdb");
  325. return;
  326. }
  327. ecode = ntdb_store( dst_ntdb, key, dbuf, NTDB_REPLACE);
  328. if (ecode)
  329. terror(ecode, "failed to move record");
  330. else
  331. printf("record moved\n");
  332. ntdb_close( dst_ntdb );
  333. }
  334. static int print_rec(struct ntdb_context *the_ntdb, NTDB_DATA key, NTDB_DATA dbuf, void *state)
  335. {
  336. printf("\nkey %d bytes\n", (int)key.dsize);
  337. print_asc((const char *)key.dptr, key.dsize);
  338. printf("\ndata %d bytes\n", (int)dbuf.dsize);
  339. print_data((const char *)dbuf.dptr, dbuf.dsize);
  340. return 0;
  341. }
  342. static int print_key(struct ntdb_context *the_ntdb, NTDB_DATA key, NTDB_DATA dbuf, void *state)
  343. {
  344. printf("key %d bytes: ", (int)key.dsize);
  345. print_asc((const char *)key.dptr, key.dsize);
  346. printf("\n");
  347. return 0;
  348. }
  349. static int print_hexkey(struct ntdb_context *the_ntdb, NTDB_DATA key, NTDB_DATA dbuf, void *state)
  350. {
  351. printf("key %d bytes\n", (int)key.dsize);
  352. print_data((const char *)key.dptr, key.dsize);
  353. printf("\n");
  354. return 0;
  355. }
  356. static int total_bytes;
  357. static int traverse_fn(struct ntdb_context *the_ntdb, NTDB_DATA key, NTDB_DATA dbuf, void *state)
  358. {
  359. total_bytes += dbuf.dsize;
  360. return 0;
  361. }
  362. static void info_ntdb(void)
  363. {
  364. enum NTDB_ERROR ecode;
  365. char *summary;
  366. ecode = ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &summary);
  367. if (ecode) {
  368. terror(ecode, "Getting summary");
  369. } else {
  370. printf("%s", summary);
  371. free(summary);
  372. }
  373. }
  374. static void speed_ntdb(const char *tlimit)
  375. {
  376. unsigned timelimit = tlimit?atoi(tlimit):0;
  377. double t;
  378. int ops;
  379. if (timelimit == 0) timelimit = 5;
  380. ops = 0;
  381. printf("Testing store speed for %u seconds\n", timelimit);
  382. _start_timer();
  383. do {
  384. long int r = random();
  385. NTDB_DATA key, dbuf;
  386. key = ntdb_mkdata("store test", strlen("store test"));
  387. dbuf.dptr = (unsigned char *)&r;
  388. dbuf.dsize = sizeof(r);
  389. ntdb_store(ntdb, key, dbuf, NTDB_REPLACE);
  390. t = _end_timer();
  391. ops++;
  392. } while (t < timelimit);
  393. printf("%10.3f ops/sec\n", ops/t);
  394. ops = 0;
  395. printf("Testing fetch speed for %u seconds\n", timelimit);
  396. _start_timer();
  397. do {
  398. long int r = random();
  399. NTDB_DATA key, dbuf;
  400. key = ntdb_mkdata("store test", strlen("store test"));
  401. dbuf.dptr = (unsigned char *)&r;
  402. dbuf.dsize = sizeof(r);
  403. ntdb_fetch(ntdb, key, &dbuf);
  404. t = _end_timer();
  405. ops++;
  406. } while (t < timelimit);
  407. printf("%10.3f ops/sec\n", ops/t);
  408. ops = 0;
  409. printf("Testing transaction speed for %u seconds\n", timelimit);
  410. _start_timer();
  411. do {
  412. long int r = random();
  413. NTDB_DATA key, dbuf;
  414. key = ntdb_mkdata("transaction test", strlen("transaction test"));
  415. dbuf.dptr = (unsigned char *)&r;
  416. dbuf.dsize = sizeof(r);
  417. ntdb_transaction_start(ntdb);
  418. ntdb_store(ntdb, key, dbuf, NTDB_REPLACE);
  419. ntdb_transaction_commit(ntdb);
  420. t = _end_timer();
  421. ops++;
  422. } while (t < timelimit);
  423. printf("%10.3f ops/sec\n", ops/t);
  424. ops = 0;
  425. printf("Testing traverse speed for %u seconds\n", timelimit);
  426. _start_timer();
  427. do {
  428. ntdb_traverse(ntdb, traverse_fn, NULL);
  429. t = _end_timer();
  430. ops++;
  431. } while (t < timelimit);
  432. printf("%10.3f ops/sec\n", ops/t);
  433. }
  434. static void toggle_mmap(void)
  435. {
  436. disable_mmap = !disable_mmap;
  437. if (disable_mmap) {
  438. printf("mmap is disabled\n");
  439. } else {
  440. printf("mmap is enabled\n");
  441. }
  442. }
  443. static char *ntdb_getline(const char *prompt)
  444. {
  445. static char thisline[1024];
  446. char *p;
  447. fputs(prompt, stdout);
  448. thisline[0] = 0;
  449. p = fgets(thisline, sizeof(thisline)-1, stdin);
  450. if (p) p = strchr(p, '\n');
  451. if (p) *p = 0;
  452. return p?thisline:NULL;
  453. }
  454. static int do_delete_fn(struct ntdb_context *the_ntdb, NTDB_DATA key, NTDB_DATA dbuf,
  455. void *state)
  456. {
  457. return ntdb_delete(the_ntdb, key);
  458. }
  459. static void first_record(struct ntdb_context *the_ntdb, NTDB_DATA *pkey)
  460. {
  461. NTDB_DATA dbuf;
  462. enum NTDB_ERROR ecode;
  463. ecode = ntdb_firstkey(the_ntdb, pkey);
  464. if (!ecode)
  465. ecode = ntdb_fetch(the_ntdb, *pkey, &dbuf);
  466. if (ecode) terror(ecode, "fetch failed");
  467. else {
  468. print_rec(the_ntdb, *pkey, dbuf, NULL);
  469. }
  470. }
  471. static void next_record(struct ntdb_context *the_ntdb, NTDB_DATA *pkey)
  472. {
  473. NTDB_DATA dbuf;
  474. enum NTDB_ERROR ecode;
  475. ecode = ntdb_nextkey(the_ntdb, pkey);
  476. if (!ecode)
  477. ecode = ntdb_fetch(the_ntdb, *pkey, &dbuf);
  478. if (ecode)
  479. terror(ecode, "fetch failed");
  480. else
  481. print_rec(the_ntdb, *pkey, dbuf, NULL);
  482. }
  483. static void check_db(struct ntdb_context *the_ntdb)
  484. {
  485. if (!the_ntdb) {
  486. printf("Error: No database opened!\n");
  487. } else {
  488. if (ntdb_check(the_ntdb, NULL, NULL) != 0)
  489. printf("Integrity check for the opened database failed.\n");
  490. else
  491. printf("Database integrity is OK.\n");
  492. }
  493. }
  494. static int do_command(void)
  495. {
  496. COMMAND_TABLE *ctp = cmd_table;
  497. enum commands mycmd = CMD_HELP;
  498. int cmd_len;
  499. if (cmdname && strlen(cmdname) == 0) {
  500. mycmd = CMD_NEXT;
  501. } else {
  502. while (ctp->name) {
  503. cmd_len = strlen(ctp->name);
  504. if (strncmp(ctp->name,cmdname,cmd_len) == 0) {
  505. mycmd = ctp->cmd;
  506. break;
  507. }
  508. ctp++;
  509. }
  510. }
  511. switch (mycmd) {
  512. case CMD_CREATE_NTDB:
  513. bIterate = 0;
  514. create_ntdb(arg1);
  515. return 0;
  516. case CMD_OPEN_NTDB:
  517. bIterate = 0;
  518. open_ntdb(arg1);
  519. return 0;
  520. case CMD_SYSTEM:
  521. /* Shell command */
  522. if (system(arg1) == -1) {
  523. terror(NTDB_SUCCESS, "system() call failed\n");
  524. }
  525. return 0;
  526. case CMD_QUIT:
  527. return 1;
  528. default:
  529. /* all the rest require a open database */
  530. if (!ntdb) {
  531. bIterate = 0;
  532. terror(NTDB_SUCCESS, "database not open");
  533. help();
  534. return 0;
  535. }
  536. switch (mycmd) {
  537. case CMD_TRANSACTION_START:
  538. bIterate = 0;
  539. ntdb_transaction_start(ntdb);
  540. return 0;
  541. case CMD_TRANSACTION_COMMIT:
  542. bIterate = 0;
  543. ntdb_transaction_commit(ntdb);
  544. return 0;
  545. case CMD_TRANSACTION_CANCEL:
  546. bIterate = 0;
  547. ntdb_transaction_cancel(ntdb);
  548. return 0;
  549. case CMD_ERASE:
  550. bIterate = 0;
  551. ntdb_traverse(ntdb, do_delete_fn, NULL);
  552. return 0;
  553. case CMD_DUMP:
  554. bIterate = 0;
  555. ntdb_traverse(ntdb, print_rec, NULL);
  556. return 0;
  557. case CMD_INSERT:
  558. bIterate = 0;
  559. insert_ntdb(arg1, arg1len,arg2,arg2len);
  560. return 0;
  561. case CMD_MOVE:
  562. bIterate = 0;
  563. move_rec(arg1,arg1len,arg2);
  564. return 0;
  565. case CMD_STORE:
  566. bIterate = 0;
  567. store_ntdb(arg1,arg1len,arg2,arg2len);
  568. return 0;
  569. case CMD_SHOW:
  570. bIterate = 0;
  571. show_ntdb(arg1, arg1len);
  572. return 0;
  573. case CMD_KEYS:
  574. ntdb_traverse(ntdb, print_key, NULL);
  575. return 0;
  576. case CMD_HEXKEYS:
  577. ntdb_traverse(ntdb, print_hexkey, NULL);
  578. return 0;
  579. case CMD_DELETE:
  580. bIterate = 0;
  581. delete_ntdb(arg1,arg1len);
  582. return 0;
  583. #if 0
  584. case CMD_LIST_HASH_FREE:
  585. ntdb_dump_all(ntdb);
  586. return 0;
  587. case CMD_LIST_FREE:
  588. ntdb_printfreelist(ntdb);
  589. return 0;
  590. #endif
  591. case CMD_INFO:
  592. info_ntdb();
  593. return 0;
  594. case CMD_SPEED:
  595. speed_ntdb(arg1);
  596. return 0;
  597. case CMD_MMAP:
  598. toggle_mmap();
  599. return 0;
  600. case CMD_FIRST:
  601. bIterate = 1;
  602. first_record(ntdb, &iterate_kbuf);
  603. return 0;
  604. case CMD_NEXT:
  605. if (bIterate)
  606. next_record(ntdb, &iterate_kbuf);
  607. return 0;
  608. case CMD_CHECK:
  609. check_db(ntdb);
  610. return 0;
  611. case CMD_HELP:
  612. help();
  613. return 0;
  614. case CMD_CREATE_NTDB:
  615. case CMD_OPEN_NTDB:
  616. case CMD_SYSTEM:
  617. case CMD_QUIT:
  618. /*
  619. * unhandled commands. cases included here to avoid compiler
  620. * warnings.
  621. */
  622. return 0;
  623. }
  624. }
  625. return 0;
  626. }
  627. static char *convert_string(char *instring, size_t *sizep)
  628. {
  629. size_t length = 0;
  630. char *outp, *inp;
  631. char temp[3];
  632. outp = inp = instring;
  633. while (*inp) {
  634. if (*inp == '\\') {
  635. inp++;
  636. if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) {
  637. temp[0] = *inp++;
  638. temp[1] = '\0';
  639. if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) {
  640. temp[1] = *inp++;
  641. temp[2] = '\0';
  642. }
  643. *outp++ = (char)strtol((const char *)temp,NULL,16);
  644. } else {
  645. *outp++ = *inp++;
  646. }
  647. } else {
  648. *outp++ = *inp++;
  649. }
  650. length++;
  651. }
  652. *sizep = length;
  653. return instring;
  654. }
  655. int main(int argc, char *argv[])
  656. {
  657. cmdname = "";
  658. arg1 = NULL;
  659. arg1len = 0;
  660. arg2 = NULL;
  661. arg2len = 0;
  662. if (argv[1]) {
  663. cmdname = "open";
  664. arg1 = argv[1];
  665. do_command();
  666. cmdname = "";
  667. arg1 = NULL;
  668. }
  669. switch (argc) {
  670. case 1:
  671. case 2:
  672. /* Interactive mode */
  673. while ((cmdname = ntdb_getline("ntdb> "))) {
  674. arg2 = arg1 = NULL;
  675. if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) {
  676. arg1++;
  677. arg2 = arg1;
  678. while (*arg2) {
  679. if (*arg2 == ' ') {
  680. *arg2++ = '\0';
  681. break;
  682. }
  683. if ((*arg2++ == '\\') && (*arg2 == ' ')) {
  684. arg2++;
  685. }
  686. }
  687. }
  688. if (arg1) arg1 = convert_string(arg1,&arg1len);
  689. if (arg2) arg2 = convert_string(arg2,&arg2len);
  690. if (do_command()) break;
  691. }
  692. break;
  693. case 5:
  694. arg2 = convert_string(argv[4],&arg2len);
  695. case 4:
  696. arg1 = convert_string(argv[3],&arg1len);
  697. case 3:
  698. cmdname = argv[2];
  699. default:
  700. do_command();
  701. break;
  702. }
  703. if (ntdb) ntdb_close(ntdb);
  704. return 0;
  705. }