zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdbtool.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdbtool.c
new file mode 100644
index 0000000..eeac0c8
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdbtool.c
@@ -0,0 +1,621 @@
+/*
+   Unix SMB/CIFS implementation.
+   Samba database functions
+   Copyright (C) Andrew Tridgell              1999-2000
+   Copyright (C) Paul `Rusty' Russell		   2000
+   Copyright (C) Jeremy Allison			   2000
+   Copyright (C) Andrew Esh                        2001
+
+   This program 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.
+
+   This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <signal.h>
+#include <stdarg.h>
+
+#include "tdb.h"
+
+static int do_command(void);
+const char *cmdname;
+char *arg1, *arg2;
+size_t arg1len, arg2len;
+int bIterate = 0;
+char *line;
+TDB_DATA iterate_kbuf;
+char cmdline[1024];
+
+enum commands {
+	CMD_CREATE_TDB,
+	CMD_OPEN_TDB,
+	CMD_ERASE,
+	CMD_DUMP,
+	CMD_INSERT,
+	CMD_MOVE,
+	CMD_STORE,
+	CMD_SHOW,
+	CMD_KEYS,
+	CMD_HEXKEYS,
+	CMD_DELETE,
+	CMD_LIST_HASH_FREE,
+	CMD_LIST_FREE,
+	CMD_INFO,
+	CMD_FIRST,
+	CMD_NEXT,
+	CMD_SYSTEM,
+	CMD_QUIT,
+	CMD_HELP
+};
+
+typedef struct {
+	const char *name;
+	enum commands cmd;
+} COMMAND_TABLE;
+
+COMMAND_TABLE cmd_table[] = {
+	{"create",	CMD_CREATE_TDB},
+	{"open",	CMD_OPEN_TDB},
+	{"erase",	CMD_ERASE},
+	{"dump",	CMD_DUMP},
+	{"insert",	CMD_INSERT},
+	{"move",	CMD_MOVE},
+	{"store",	CMD_STORE},
+	{"show",	CMD_SHOW},
+	{"keys",	CMD_KEYS},
+	{"hexkeys",	CMD_HEXKEYS},
+	{"delete",	CMD_DELETE},
+	{"list",	CMD_LIST_HASH_FREE},
+	{"free",	CMD_LIST_FREE},
+	{"info",	CMD_INFO},
+	{"first",	CMD_FIRST},
+	{"1",		CMD_FIRST},
+	{"next",	CMD_NEXT},
+	{"n",		CMD_NEXT},
+	{"quit",	CMD_QUIT},
+	{"q",		CMD_QUIT},
+	{"!",		CMD_SYSTEM},
+	{NULL,		CMD_HELP}
+};
+
+/* a tdb tool for manipulating a tdb database */
+
+static TDB_CONTEXT *tdb;
+
+static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
+static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
+static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
+
+static void print_asc(const char *buf,int len)
+{
+	int i;
+
+	/* We're probably printing ASCII strings so don't try to display
+	   the trailing NULL character. */
+
+	if (buf[len - 1] == 0)
+	        len--;
+
+	for (i=0;i<len;i++)
+		printf("%c",isprint(buf[i])?buf[i]:'.');
+}
+
+static void print_data(const char *buf,int len)
+{
+	int i=0;
+	if (len<=0) return;
+	printf("[%03X] ",i);
+	for (i=0;i<len;) {
+		printf("%02X ",(int)buf[i]);
+		i++;
+		if (i%8 == 0) printf(" ");
+		if (i%16 == 0) {
+			print_asc(&buf[i-16],8); printf(" ");
+			print_asc(&buf[i-8],8); printf("\n");
+			if (i<len) printf("[%03X] ",i);
+		}
+	}
+	if (i%16) {
+		int n;
+
+		n = 16 - (i%16);
+		printf(" ");
+		if (n>8) printf(" ");
+		while (n--) printf("   ");
+
+		n = i%16;
+		if (n > 8) n = 8;
+		print_asc(&buf[i-(i%16)],n); printf(" ");
+		n = (i%16) - n;
+		if (n>0) print_asc(&buf[i-n],n);
+		printf("\n");
+	}
+}
+
+static void help(void)
+{
+	printf("\n"
+"tdbtool: \n"
+"  create    dbname     : create a database\n"
+"  open      dbname     : open an existing database\n"
+"  erase                : erase the database\n"
+"  dump                 : dump the database as strings\n"
+"  keys                 : dump the database keys as strings\n"
+"  hexkeys              : dump the database keys as hex values\n"
+"  info                 : print summary info about the database\n"
+"  insert    key  data  : insert a record\n"
+"  move      key  file  : move a record to a destination tdb\n"
+"  store     key  data  : store a record (replace)\n"
+"  show      key        : show a record by key\n"
+"  delete    key        : delete a record by key\n"
+"  list                 : print the database hash table and freelist\n"
+"  free                 : print the database freelist\n"
+"  ! command            : execute system command\n"
+"  1 | first            : print the first record\n"
+"  n | next             : print the next record\n"
+"  q | quit             : terminate\n"
+"  \\n                   : repeat 'next' command\n"
+"\n");
+}
+
+static void terror(const char *why)
+{
+	printf("%s\n", why);
+}
+
+static void create_tdb(const char *tdbname)
+{
+	if (tdb) tdb_close(tdb);
+	tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST,
+		       O_RDWR | O_CREAT | O_TRUNC, 0600);
+	if (!tdb) {
+		printf("Could not create %s: %s\n", tdbname, strerror(errno));
+	}
+}
+
+static void open_tdb(const char *tdbname)
+{
+	if (tdb) tdb_close(tdb);
+	tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600);
+	if (!tdb) {
+		printf("Could not open %s: %s\n", tdbname, strerror(errno));
+	}
+}
+
+static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen)
+{
+	TDB_DATA key, dbuf;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+	dbuf.dptr = (unsigned char *)data;
+	dbuf.dsize = datalen;
+
+	if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) {
+		terror("insert failed");
+	}
+}
+
+static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen)
+{
+	TDB_DATA key, dbuf;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	if ((data == NULL) || (datalen == 0)) {
+		terror("need data");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+	dbuf.dptr = (unsigned char *)data;
+	dbuf.dsize = datalen;
+
+	printf("Storing key:\n");
+	print_rec(tdb, key, dbuf, NULL);
+
+	if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
+		terror("store failed");
+	}
+}
+
+static void show_tdb(char *keyname, size_t keylen)
+{
+	TDB_DATA key, dbuf;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+
+	dbuf = tdb_fetch(tdb, key);
+	if (!dbuf.dptr) {
+	    terror("fetch failed");
+	    return;
+	}
+
+	print_rec(tdb, key, dbuf, NULL);
+
+	free( dbuf.dptr );
+
+	return;
+}
+
+static void delete_tdb(char *keyname, size_t keylen)
+{
+	TDB_DATA key;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+
+	if (tdb_delete(tdb, key) != 0) {
+		terror("delete failed");
+	}
+}
+
+static void move_rec(char *keyname, size_t keylen, char* tdbname)
+{
+	TDB_DATA key, dbuf;
+	TDB_CONTEXT *dst_tdb;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	if ( !tdbname ) {
+		terror("need destination tdb name");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+
+	dbuf = tdb_fetch(tdb, key);
+	if (!dbuf.dptr) {
+		terror("fetch failed");
+		return;
+	}
+
+	print_rec(tdb, key, dbuf, NULL);
+
+	dst_tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600);
+	if ( !dst_tdb ) {
+		terror("unable to open destination tdb");
+		return;
+	}
+
+	if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) {
+		terror("failed to move record");
+	}
+	else
+		printf("record moved\n");
+
+	tdb_close( dst_tdb );
+
+	return;
+}
+
+static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+	printf("\nkey %d bytes\n", (int)key.dsize);
+	print_asc((const char *)key.dptr, key.dsize);
+	printf("\ndata %d bytes\n", (int)dbuf.dsize);
+	print_data((const char *)dbuf.dptr, dbuf.dsize);
+	return 0;
+}
+
+static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+	printf("key %d bytes: ", (int)key.dsize);
+	print_asc((const char *)key.dptr, key.dsize);
+	printf("\n");
+	return 0;
+}
+
+static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+	printf("key %d bytes\n", (int)key.dsize);
+	print_data((const char *)key.dptr, key.dsize);
+	printf("\n");
+	return 0;
+}
+
+static int total_bytes;
+
+static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+	total_bytes += dbuf.dsize;
+	return 0;
+}
+
+static void info_tdb(void)
+{
+	int count;
+	total_bytes = 0;
+	if ((count = tdb_traverse(tdb, traverse_fn, NULL)) == -1)
+		printf("Error = %s\n", tdb_errorstr(tdb));
+	else
+		printf("%d records totalling %d bytes\n", count, total_bytes);
+}
+
+static char *tdb_getline(const char *prompt)
+{
+	static char thisline[1024];
+	char *p;
+	fputs(prompt, stdout);
+	thisline[0] = 0;
+	p = fgets(thisline, sizeof(thisline)-1, stdin);
+	if (p) p = strchr(p, '\n');
+	if (p) *p = 0;
+	return p?thisline:NULL;
+}
+
+static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
+                     void *state)
+{
+    return tdb_delete(the_tdb, key);
+}
+
+static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
+{
+	TDB_DATA dbuf;
+	*pkey = tdb_firstkey(the_tdb);
+
+	dbuf = tdb_fetch(the_tdb, *pkey);
+	if (!dbuf.dptr) terror("fetch failed");
+	else {
+		print_rec(the_tdb, *pkey, dbuf, NULL);
+	}
+}
+
+static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
+{
+	TDB_DATA dbuf;
+	*pkey = tdb_nextkey(the_tdb, *pkey);
+
+	dbuf = tdb_fetch(the_tdb, *pkey);
+	if (!dbuf.dptr)
+		terror("fetch failed");
+	else
+		print_rec(the_tdb, *pkey, dbuf, NULL);
+}
+
+static int do_command(void)
+{
+	COMMAND_TABLE *ctp = cmd_table;
+	enum commands mycmd = CMD_HELP;
+	int cmd_len;
+
+	if (cmdname && strlen(cmdname) == 0) {
+	    mycmd = CMD_NEXT;
+	} else {
+	    while (ctp->name) {
+		cmd_len = strlen(ctp->name);
+		if (strncmp(ctp->name,cmdname,cmd_len) == 0) {
+			mycmd = ctp->cmd;
+			break;
+		}
+		ctp++;
+	    }
+	}
+
+	switch (mycmd) {
+	case CMD_CREATE_TDB:
+            bIterate = 0;
+            create_tdb(arg1);
+	    return 0;
+	case CMD_OPEN_TDB:
+            bIterate = 0;
+            open_tdb(arg1);
+            return 0;
+	case CMD_SYSTEM:
+	    /* Shell command */
+	    system(arg1);
+	    return 0;
+	case CMD_QUIT:
+	    return 1;
+	default:
+	    /* all the rest require a open database */
+	    if (!tdb) {
+		bIterate = 0;
+		terror("database not open");
+		help();
+		return 0;
+	    }
+	    switch (mycmd) {
+	    case CMD_ERASE:
+		bIterate = 0;
+		tdb_traverse(tdb, do_delete_fn, NULL);
+		return 0;
+	    case CMD_DUMP:
+		bIterate = 0;
+		tdb_traverse(tdb, print_rec, NULL);
+		return 0;
+	    case CMD_INSERT:
+		bIterate = 0;
+		insert_tdb(arg1, arg1len,arg2,arg2len);
+		return 0;
+	    case CMD_MOVE:
+		bIterate = 0;
+		move_rec(arg1,arg1len,arg2);
+		return 0;
+	    case CMD_STORE:
+		bIterate = 0;
+		store_tdb(arg1,arg1len,arg2,arg2len);
+		return 0;
+	    case CMD_SHOW:
+		bIterate = 0;
+		show_tdb(arg1, arg1len);
+		return 0;
+	    case CMD_KEYS:
+		tdb_traverse(tdb, print_key, NULL);
+		return 0;
+	    case CMD_HEXKEYS:
+		tdb_traverse(tdb, print_hexkey, NULL);
+		return 0;
+	    case CMD_DELETE:
+		bIterate = 0;
+		delete_tdb(arg1,arg1len);
+		return 0;
+	    case CMD_LIST_HASH_FREE:
+		tdb_dump_all(tdb);
+		return 0;
+	    case CMD_LIST_FREE:
+		tdb_printfreelist(tdb);
+		return 0;
+	    case CMD_INFO:
+		info_tdb();
+		return 0;
+	    case CMD_FIRST:
+		bIterate = 1;
+		first_record(tdb, &iterate_kbuf);
+		return 0;
+	    case CMD_NEXT:
+	       if (bIterate)
+		  next_record(tdb, &iterate_kbuf);
+		return 0;
+	    case CMD_HELP:
+		help();
+		return 0;
+            case CMD_CREATE_TDB:
+            case CMD_OPEN_TDB:
+            case CMD_SYSTEM:
+            case CMD_QUIT:
+                /*
+                 * unhandled commands.  cases included here to avoid compiler
+                 * warnings.
+                 */
+                return 0;
+	    }
+	}
+
+	return 0;
+}
+
+static char *convert_string(char *instring, size_t *sizep)
+{
+    size_t length = 0;
+    char *outp, *inp;
+    char temp[3];
+
+
+    outp = inp = instring;
+
+    while (*inp) {
+	if (*inp == '\\') {
+	    inp++;
+	    if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) {
+		temp[0] = *inp++;
+		temp[1] = '\0';
+		if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) {
+		    temp[1] = *inp++;
+		    temp[2] = '\0';
+		}
+		*outp++ = (char)strtol((const char *)temp,NULL,16);
+	    } else {
+		*outp++ = *inp++;
+	    }
+	} else {
+	    *outp++ = *inp++;
+	}
+	length++;
+    }
+    *sizep = length;
+    return instring;
+}
+
+int main(int argc, char *argv[])
+{
+    cmdname = "";
+    arg1 = NULL;
+    arg1len = 0;
+    arg2 = NULL;
+    arg2len = 0;
+
+    if (argv[1]) {
+	cmdname = "open";
+	arg1 = argv[1];
+        do_command();
+	cmdname =  "";
+	arg1 = NULL;
+    }
+
+    switch (argc) {
+	case 1:
+	case 2:
+	    /* Interactive mode */
+	    while ((cmdname = tdb_getline("tdb> "))) {
+		arg2 = arg1 = NULL;
+		if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) {
+		    arg1++;
+		    arg2 = arg1;
+		    while (*arg2) {
+			if (*arg2 == ' ') {
+			    *arg2++ = '\0';
+			    break;
+			}
+			if ((*arg2++ == '\\') && (*arg2 == ' ')) {
+			    arg2++;
+			}
+		    }
+		}
+		if (arg1) arg1 = convert_string(arg1,&arg1len);
+		if (arg2) arg2 = convert_string(arg2,&arg2len);
+		if (do_command()) break;
+	    }
+	    break;
+	case 5:
+	    arg2 = convert_string(argv[4],&arg2len);
+	case 4:
+	    arg1 = convert_string(argv[3],&arg1len);
+	case 3:
+	    cmdname = argv[2];
+	default:
+	    do_command();
+	    break;
+    }
+
+    if (tdb) tdb_close(tdb);
+
+    return 0;
+}