summaryrefslogtreecommitdiff
path: root/source3/tdb
diff options
context:
space:
mode:
authorDavid O'Neill <dmo@samba.org>2001-01-29 21:34:08 +0000
committerDavid O'Neill <dmo@samba.org>2001-01-29 21:34:08 +0000
commit2506c61ab3bd667d54c5e004cc80ce5e40643b5d (patch)
treeb31d685b78a8ba71f3599aa481ce281d5fea290b /source3/tdb
parent9ec19336e519ef3543eb9d3eafb24585657a2e8d (diff)
downloadsamba-2506c61ab3bd667d54c5e004cc80ce5e40643b5d.tar.gz
samba-2506c61ab3bd667d54c5e004cc80ce5e40643b5d.tar.bz2
samba-2506c61ab3bd667d54c5e004cc80ce5e40643b5d.zip
Changes from APPLIANCE_HEAD:
source/include/proto.h - make proto source/printing/nt_printing.c source/rpc_server/srv_spoolss_nt.c - Fix for the overwriting of printerdata entries when WinNT and Win2k are modifying printer parameters on PCL printers. Turns out that Win2k creates a printer with a NULL devmode entry and then expects to set it on *OPEN* (yes this is insane). So we cannot return a "default" devmode for a printer - and we must allow an open to set it. source/tdb/tdb.c - Show freelist in an easier format. Show total free. - When storing a new record, allocate memory for the key + data before the tdb_allocate() as if the malloc fails a (sparse) hole is left in the tdb. source/tdb/tdbtool.c - Show freelist in an easier format. Show total free. source/tdb/Makefile - cleaned up Makefile dependancies source/smbd/lanman.c - Fix for Win9x corrupting it's own parameter string. source/printing/printfsp.c source/printing/printing.c source/rpc_server/srv_spoolss_nt.c source/smbd/close.c - Added normal close parameter into print_fsp_end() which treats an abnormal close as error condition and deletes the spool file. (This used to be commit 025f7a092ad258ff774e3f5e53737f8210cc8af6)
Diffstat (limited to 'source3/tdb')
-rw-r--r--source3/tdb/Makefile14
-rw-r--r--source3/tdb/tdb.c32
-rw-r--r--source3/tdb/tdbtool.c83
3 files changed, 101 insertions, 28 deletions
diff --git a/source3/tdb/Makefile b/source3/tdb/Makefile
index 01de7d244b..196187eef1 100644
--- a/source3/tdb/Makefile
+++ b/source3/tdb/Makefile
@@ -4,18 +4,20 @@
CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DHAVE_MMAP=1
CC = gcc
+
PROGS = tdbtest tdbtool tdbtorture
+TDB_OBJ = tdb.o spinlock.o
default: $(PROGS)
-tdbtest: tdbtest.o tdb.o spinlock.o
- $(CC) $(CFLAGS) -o tdbtest tdbtest.o tdb.o spinlock.o -lgdbm
+tdbtest: tdbtest.o $(TDB_OBJ)
+ $(CC) $(CFLAGS) -o tdbtest tdbtest.o $(TDB_OBJ) -lgdbm
-tdbtool: tdbtool.o tdb.o spinlock.o
- $(CC) $(CFLAGS) -o tdbtool tdbtool.o tdb.o spinlock.o
+tdbtool: tdbtool.o $(TDB_OBJ)
+ $(CC) $(CFLAGS) -o tdbtool tdbtool.o $(TDB_OBJ)
-tdbtorture: tdbtorture.o tdb.o
- $(CC) $(CFLAGS) -o tdbtorture tdbtorture.o tdb.o spinlock.o
+tdbtorture: tdbtorture.o $(TDB_OBJ)
+ $(CC) $(CFLAGS) -o tdbtorture tdbtorture.o $(TDB_OBJ)
clean:
rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index 944a734ddc..39d061b0a8 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -84,10 +84,10 @@ static void *tdb_mmap(tdb_len size, int readonly, int fd)
void *ret = NULL;
#ifdef HAVE_MMAP
ret = mmap(NULL, size, PROT_READ | (readonly ? 0 : PROT_WRITE), MAP_SHARED|MAP_FILE, fd, 0);
-#endif
- if (ret == (void *)-1)
- ret = NULL;
+ if (ret == (void *)-1)
+ ret = NULL;
+#endif
return ret;
}
@@ -302,7 +302,8 @@ static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset,
#ifdef TDB_DEBUG
void tdb_printfreelist(TDB_CONTEXT *tdb)
{
- tdb_off offset, rec_ptr, last_ptr;
+ long total_free = 0;
+ tdb_off offset, rec_ptr, last_ptr;
struct list_struct rec, lastrec, newrec;
tdb_lock(tdb, -1, F_WRLCK);
@@ -326,11 +327,13 @@ void tdb_printfreelist(TDB_CONTEXT *tdb)
return;
}
- printf("entry offset=[0x%08x], rec.rec_len = [0x%08x]\n", rec.next, rec.rec_len );
+ printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)]\n", rec.next, rec.rec_len, rec.rec_len );
+ total_free += rec.rec_len;
/* move to the next record */
rec_ptr = rec.next;
}
+ printf("total rec_len = [0x%08x (%d)]\n", total_free, total_free );
tdb_unlock(tdb, -1, F_WRLCK);
}
@@ -1013,6 +1016,17 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
coalescing with `allocated' block before it's updated. */
if (flag != TDB_INSERT) tdb_delete(tdb, key);
+ /* Copy key+value *before* allocating free space in case malloc
+ fails and we are left with a dead spot in the tdb. */
+
+ if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) {
+ tdb->ecode = TDB_ERR_OOM;
+ goto fail;
+ }
+
+ memcpy(p, key.dptr, key.dsize);
+ memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
+
/* now we're into insert / modify / replace of a record which
* we know could not be optimised by an in-place store (for
* various reasons). */
@@ -1027,18 +1041,12 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
rec.full_hash = hash;
rec.magic = TDB_MAGIC;
- if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) {
- tdb->ecode = TDB_ERR_OOM;
- goto fail;
- }
-
- memcpy(p, key.dptr, key.dsize);
- memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
/* write out and point the top of the hash chain at it */
if (rec_write(tdb, rec_ptr, &rec) == -1
|| tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1
|| ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) {
fail:
+ /* Need to tdb_unallocate() here */
ret = -1;
}
out:
diff --git a/source3/tdb/tdbtool.c b/source3/tdb/tdbtool.c
index 508adc5d54..1b038226d0 100644
--- a/source3/tdb/tdbtool.c
+++ b/source3/tdb/tdbtool.c
@@ -12,6 +12,27 @@
/* a tdb tool for manipulating a tdb database */
+#define FSTRING_LEN 128
+typedef char fstring[FSTRING_LEN];
+
+typedef struct connections_key {
+ pid_t pid;
+ int cnum;
+ fstring name;
+} connections_key;
+
+typedef struct connections_data {
+ int magic;
+ pid_t pid;
+ int cnum;
+ uid_t uid;
+ gid_t gid;
+ char name[24];
+ char addr[24];
+ char machine[128];
+ time_t start;
+} connections_data;
+
static TDB_CONTEXT *tdb;
static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
@@ -180,13 +201,41 @@ static void delete_tdb(void)
}
}
+static int print_conn_key(TDB_DATA key)
+{
+ printf( "pid =%5d ", ((connections_key*)key.dptr)->pid);
+ printf( "cnum =%10d ", ((connections_key*)key.dptr)->cnum);
+ printf( "name =[%s]\n", ((connections_key*)key.dptr)->name);
+ return 0;
+}
+
+static int print_conn_data(TDB_DATA dbuf)
+{
+ printf( "pid =%5d ", ((connections_data*)dbuf.dptr)->pid);
+ printf( "cnum =%10d ", ((connections_data*)dbuf.dptr)->cnum);
+ printf( "name =[%s]\n", ((connections_data*)dbuf.dptr)->name);
+
+ printf( "uid =%5d ", ((connections_data*)dbuf.dptr)->uid);
+ printf( "addr =[%s]\n", ((connections_data*)dbuf.dptr)->addr);
+ printf( "gid =%5d ", ((connections_data*)dbuf.dptr)->gid);
+ printf( "machine=[%s]\n", ((connections_data*)dbuf.dptr)->machine);
+ printf( "start = %s\n", ctime(&((connections_data*)dbuf.dptr)->start));
+ return 0;
+}
+
static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
+#if 0
+ print_conn_key(key);
+ print_conn_data(dbuf);
+ return 0;
+#else
printf("\nkey %d bytes\n", key.dsize);
print_data(key.dptr, key.dsize);
printf("data %d bytes\n", dbuf.dsize);
print_data(dbuf.dptr, dbuf.dsize);
return 0;
+#endif
}
static int total_bytes;
@@ -240,13 +289,16 @@ static void next_record(TDB_CONTEXT *tdb, TDB_DATA *pkey)
*pkey = tdb_nextkey(tdb, *pkey);
dbuf = tdb_fetch(tdb, *pkey);
- if (!dbuf.dptr) terror("fetch failed");
- /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
- print_rec(tdb, *pkey, dbuf, NULL);
+ if (!dbuf.dptr)
+ terror("fetch failed");
+ else
+ /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
+ print_rec(tdb, *pkey, dbuf, NULL);
}
int main(int argc, char *argv[])
{
+ int bIterate = 0;
char *line;
char *tok;
TDB_DATA iterate_kbuf;
@@ -268,9 +320,12 @@ int main(int argc, char *argv[])
}
if ((tok = strtok(line," "))==NULL) {
- continue;
+ if (bIterate)
+ next_record(tdb, &iterate_kbuf);
+ continue;
}
if (strcmp(tok,"create") == 0) {
+ bIterate = 0;
create_tdb();
continue;
} else if (strcmp(tok,"open") == 0) {
@@ -280,31 +335,39 @@ int main(int argc, char *argv[])
/* all the rest require a open database */
if (!tdb) {
+ bIterate = 0;
terror("database not open");
help();
continue;
}
if (strcmp(tok,"insert") == 0) {
+ bIterate = 0;
insert_tdb();
} else if (strcmp(tok,"store") == 0) {
+ bIterate = 0;
store_tdb();
} else if (strcmp(tok,"show") == 0) {
+ bIterate = 0;
show_tdb();
} else if (strcmp(tok,"erase") == 0) {
+ bIterate = 0;
tdb_traverse(tdb, do_delete_fn, NULL);
} else if (strcmp(tok,"delete") == 0) {
+ bIterate = 0;
delete_tdb();
} else if (strcmp(tok,"dump") == 0) {
+ bIterate = 0;
tdb_traverse(tdb, print_rec, NULL);
} else if (strcmp(tok,"info") == 0) {
info_tdb();
- } else if (strcmp(tok, "free") == 0) {
- tdb_printfreelist(tdb);
- } else if (strcmp(tok, "first") == 0) {
- first_record(tdb, &iterate_kbuf);
- } else if (strcmp(tok, "next") == 0) {
- next_record(tdb, &iterate_kbuf);
+ } else if (strcmp(tok, "free") == 0) {
+ tdb_printfreelist(tdb);
+ } else if (strcmp(tok, "first") == 0) {
+ bIterate = 1;
+ first_record(tdb, &iterate_kbuf);
+ } else if (strcmp(tok, "next") == 0) {
+ next_record(tdb, &iterate_kbuf);
} else {
help();
}