summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/include/proto.h8
-rw-r--r--source/nmbd/nmbd.c6
-rw-r--r--source/printing/nt_printing.c89
-rw-r--r--source/printing/printfsp.c4
-rw-r--r--source/printing/printing.c13
-rw-r--r--source/rpc_server/srv_spoolss_nt.c118
-rw-r--r--source/smbd/close.c4
-rw-r--r--source/smbd/lanman.c2
-rw-r--r--source/smbd/server.c5
-rw-r--r--source/tdb/tdb.c26
-rw-r--r--source/tdb/tdbtool.c83
11 files changed, 272 insertions, 86 deletions
diff --git a/source/include/proto.h b/source/include/proto.h
index 420f86ac8fa..49f12376272 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -874,7 +874,6 @@ BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipad
void endlmhosts(FILE *fp);
BOOL name_resolve_bcast(const char *name, int name_type,
struct in_addr **return_ip_list, int *return_count);
-BOOL is_ip_address(const char *name);
BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type);
BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
struct in_addr *ip);
@@ -1847,6 +1846,7 @@ BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr);
void map_printer_permissions(SEC_DESC *sd);
BOOL print_access_check(struct current_user *user, int snum, int access_type);
BOOL print_time_access_check(int snum);
+uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default);
#endif
/*The following definitions come from printing/pcap.c */
@@ -1868,7 +1868,7 @@ int sysv_printername_ok(char *name);
#if OLD_NTDOMAIN
files_struct *print_fsp_open(connection_struct *conn,char *jobname);
-void print_fsp_end(files_struct *fsp);
+void print_fsp_end(files_struct *fsp, BOOL normal_close);
#endif
/*The following definitions come from printing/printing.c */
@@ -1886,7 +1886,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode);
BOOL print_job_resume(struct current_user *user, int jobid, int *errcode);
int print_job_write(int jobid, const char *buf, int size);
int print_job_start(struct current_user *user, int snum, char *jobname);
-BOOL print_job_end(int jobid);
+BOOL print_job_end(int jobid, BOOL normal_close);
int print_queue_status(int snum,
print_queue_struct **queue,
print_status_struct *status);
@@ -3295,6 +3295,8 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
const PRINTER_DEFAULT *printer_default,
uint32 user_switch, SPOOL_USER_CTR user_ctr,
POLICY_HND *handle);
+BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
+ NT_DEVICEMODE **pp_nt_devmode);
uint32 _spoolss_closeprinter(POLICY_HND *handle);
uint32 _spoolss_deleteprinter(POLICY_HND *handle);
uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 5b9a00aad0e..f772788341e 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -686,6 +686,12 @@ static void usage(char *pname)
fault_setup((void (*)(void *))fault_continue );
+ /* POSIX demands that signals are inherited. If the invoking process has
+ * these signals masked, we will have problems, as we won't recieve them. */
+ BlockSignals(False, SIGHUP);
+ BlockSignals(False, SIGUSR1);
+ BlockSignals(False, SIGTERM);
+
CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index 9eb7dc12ed3..ff24849f0b7 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -1711,6 +1711,9 @@ uint32 del_a_printer(char *sharename)
return 0;
}
+/* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
+static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
+static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
/****************************************************************************
****************************************************************************/
static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
@@ -1775,6 +1778,7 @@ static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
info->parameters);
len += pack_devicemode(info->devmode, buf+len, buflen-len);
+
len += pack_specifics(info->specific, buf+len, buflen-len);
if (buflen != len) {
@@ -1955,8 +1959,7 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
nt_devmode->panningwidth = 0;
nt_devmode->panningheight = 0;
- nt_devmode->private=NULL;
-
+ nt_devmode->private = NULL;
return nt_devmode;
}
@@ -2088,7 +2091,7 @@ static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
if (devmode.private) {
/* the len in tdb_unpack is an int value and
- * devmoce.driverextra is only a short
+ * devmode.driverextra is only a short
*/
len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
devmode.driverextra=(uint16)extra_len;
@@ -2176,8 +2179,18 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
info.default_priority = 1;
info.setuptime = (uint32)time(NULL);
+#if 1 /* JRA - NO NOT CHANGE ! */
+ info.devmode = NULL;
+#else
+ /*
+ * We should not return a default devicemode, as this causes
+ * Win2K to not send the correct one on PCL drivers. It needs to
+ * see a null devicemode so it can then overwrite the devicemode
+ * on OpenPrinterEx. Yes this *is* insane :-). JRA.
+ */
if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
goto fail;
+#endif
if (!nt_printing_getsec(sharename, &info.secdesc_buf))
goto fail;
@@ -2399,9 +2412,13 @@ uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
NTTIME time_nt;
time_t time_unix = time(NULL);
unix_to_nt_time(&time_nt, time_unix);
- printer.info_2->changeid=time_nt.low;
+ if (printer.info_2->changeid==time_nt.low)
+ printer.info_2->changeid++;
+ else
+ printer.info_2->changeid=time_nt.low;
printer.info_2->c_setprinter++;
+
result=update_a_printer_2(printer.info_2);
break;
}
@@ -3123,5 +3140,69 @@ BOOL print_time_access_check(int snum)
return ok;
}
+/****************************************************************************
+ Attempt to write a default device.
+*****************************************************************************/
+
+uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+
+ uint32 result = 0;
+
+ /*
+ * Don't bother if no default devicemode was sent.
+ */
+
+ if (printer_default->devmode_cont.devmode == NULL)
+ return 0;
+
+ if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
+ return ERROR_ACCESS_DENIED;
+
+ /*
+ * Just ignore it if we already have a devmode.
+ */
+
+ if (printer->info_2->devmode != NULL)
+ goto done;
+
+ /*
+ * We don't have a devicemode and we're trying to write
+ * one. Check we have the access needed.
+ */
+
+ if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
+ DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
+ lp_servicename(snum) ));
+ result = ERROR_ACCESS_DENIED;
+ goto done;
+ }
+
+ /*
+ * Convert the on the wire devicemode format to the internal one.
+ */
+
+ if (!convert_devicemode(printer->info_2->printername,
+ printer_default->devmode_cont.devmode,
+ &printer->info_2->devmode)) {
+ result = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+
+ /*
+ * Finally write back to the tdb.
+ */
+
+ if (add_a_printer(*printer, 2)!=0) {
+ result = ERROR_ACCESS_DENIED;
+ goto done;
+ }
+
+ done:
+
+ free_a_printer(&printer, 2);
+ return result;
+}
#undef OLD_NTDOMAIN
diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c
index 9b5a4877ee2..f6ab69fd93e 100644
--- a/source/printing/printfsp.c
+++ b/source/printing/printfsp.c
@@ -82,9 +82,9 @@ files_struct *print_fsp_open(connection_struct *conn,char *jobname)
/****************************************************************************
print a file - called on closing the file
****************************************************************************/
-void print_fsp_end(files_struct *fsp)
+void print_fsp_end(files_struct *fsp, BOOL normal_close)
{
- print_job_end(fsp->print_jobid);
+ print_job_end(fsp->print_jobid, normal_close);
if (fsp->fsp_name) {
string_free(&fsp->fsp_name);
diff --git a/source/printing/printing.c b/source/printing/printing.c
index 46d872df7c0..4dbb01e8390 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -950,9 +950,11 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
/****************************************************************************
Print a file - called on closing the file. This spools the job.
+ If normal close is false then we're tearing down the jobs - treat as an
+ error.
****************************************************************************/
-BOOL print_job_end(int jobid)
+BOOL print_job_end(int jobid, BOOL normal_close)
{
struct printjob *pjob = print_job_find(jobid);
int snum, ret;
@@ -970,12 +972,17 @@ BOOL print_job_end(int jobid)
snum = print_job_snum(jobid);
- if (sys_fstat(pjob->fd, &sbuf) == 0) {
+ if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
pjob->size = sbuf.st_size;
close(pjob->fd);
pjob->fd = -1;
} else {
- /* Couldn't stat the job file, so something has gone wrong. Cleanup */
+
+ /*
+ * Not a normal close or we couldn't stat the job file,
+ * so something has gone wrong. Cleanup.
+ */
+
unlink(pjob->filename);
tdb_delete(tdb, print_key(jobid));
return False;
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 4be338d4d61..dabaca5d66e 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -669,10 +669,8 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
POLICY_HND *handle)
{
uint32 result = NT_STATUS_NO_PROBLEMO;
- SEC_DESC_BUF *sec_desc = NULL;
- uint32 acc_granted, status;
fstring name;
- extern struct current_user current_user;
+ int snum;
if (printername == NULL) {
result = ERROR_INVALID_PRINTER_NAME;
@@ -729,29 +727,38 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
}
/* NT doesn't let us connect to a printer if the connecting user
- doesn't have print permission. If no security descriptor just
- return OK. */
+ doesn't have print permission. */
- if (!nt_printing_getsec(name, &sec_desc)) {
- goto done;
- }
-
- /* Yuck - we should use the pipe_user rather than current_user but
- it doesn't seem to be filled in correctly. )-: */
+ if (!handle_is_printserver(handle)) {
- map_printer_permissions(sec_desc->sec);
+ if (!get_printer_snum(handle, &snum))
+ return ERROR_INVALID_HANDLE;
- if (!se_access_check(sec_desc->sec, &current_user, PRINTER_ACCESS_USE,
- &acc_granted, &status)) {
- DEBUG(3, ("access DENIED for printer open\n"));
- close_printer_handle(handle);
- result = ERROR_ACCESS_DENIED;
- goto done;
+ if (!print_access_check(NULL, snum, PRINTER_ACCESS_USE)) {
+ DEBUG(3, ("access DENIED for printer open\n"));
+ close_printer_handle(handle);
+ result = ERROR_ACCESS_DENIED;
+ goto done;
+ }
+
+ /*
+ * If we have a default device pointer in the
+ * printer_default struct, then we need to get
+ * the printer info from the tdb and if there is
+ * no default devicemode there then we do a *SET*
+ * here ! This is insanity.... JRA.
+ */
+
+ if (printer_default->devmode_cont.devmode != NULL) {
+ result = printer_write_default_dev( snum, printer_default);
+ if (result != 0) {
+ close_printer_handle(handle);
+ goto done;
+ }
+ }
}
done:
- free_sec_desc_buf(&sec_desc);
-
return result;
}
@@ -790,15 +797,26 @@ static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *u
return True;
}
-static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devmode)
+BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
+ NT_DEVICEMODE **pp_nt_devmode)
{
+ NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
+
+ /*
+ * Ensure nt_devmode is a valid pointer
+ * as we will be overwriting it.
+ */
+
+ if (nt_devmode == NULL)
+ if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
+ return False;
+
unistr_to_dos(nt_devmode->devicename, (const char *)devmode->devicename.buffer, 31);
unistr_to_dos(nt_devmode->formname, (const char *)devmode->formname.buffer, 31);
nt_devmode->specversion=devmode->specversion;
nt_devmode->driverversion=devmode->driverversion;
nt_devmode->size=devmode->size;
- nt_devmode->driverextra=devmode->driverextra;
nt_devmode->fields=devmode->fields;
nt_devmode->orientation=devmode->orientation;
nt_devmode->papersize=devmode->papersize;
@@ -829,16 +847,20 @@ static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devm
nt_devmode->panningwidth=devmode->panningwidth;
nt_devmode->panningheight=devmode->panningheight;
- safe_free(nt_devmode->private);
- if (nt_devmode->driverextra != 0) {
- /* if we had a previous private delete it and make a new one */
+ /*
+ * Only change private and driverextra if the incoming devmode
+ * has a new one. JRA.
+ */
+
+ if ((devmode->driverextra != 0) && (devmode->private != NULL)) {
+ safe_free(nt_devmode->private);
+ nt_devmode->driverextra=devmode->driverextra;
if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
return False;
memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
}
- else {
- nt_devmode->private = NULL;
- }
+
+ *pp_nt_devmode = nt_devmode;
return True;
}
@@ -924,7 +946,7 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **d
return True;
}
- if (!strcmp(value, "DefaultSpoolDirectory")) {
+ if (!strcmp(value, "DefaultSpoolDirectory")) {
pstring string="You are using a Samba server";
*type = 0x1;
*needed = 2*(strlen(string)+1);
@@ -1054,7 +1076,7 @@ uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
if (handle_is_printserver(handle))
found=getprinterdata_printer_server(value, type, data, needed, *out_size);
else
- found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
+ found= getprinterdata_printer(handle, value, type, data, needed, *out_size);
if (found==False) {
DEBUG(5, ("value not found, allocating %d\n", *out_size));
@@ -1072,8 +1094,9 @@ uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
if (*needed > *out_size)
return ERROR_MORE_DATA;
- else
+ else {
return NT_STATUS_NO_PROBLEMO;
+ }
}
/***************************************************************************
@@ -2308,11 +2331,11 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
printer->unknown13 = 0x0;
printer->unknown14 = 0x1;
printer->unknown15 = 0x024a; /* 586 Pentium ? */
- printer->unknown16 = 0x0;
+ printer->unknown16 = 0x0;
printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
- printer->unknown18 = 0x0;
+ printer->unknown18 = 0x0;
printer->status = nt_printq_status(status.status);
- printer->unknown20 = 0x0;
+ printer->unknown20 = 0x0;
printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
printer->unknown22 = 0x0;
printer->unknown23 = 0x6; /* 6 ???*/
@@ -3688,7 +3711,7 @@ uint32 _spoolss_enddocprinter(POLICY_HND *handle)
}
Printer->document_started=False;
- print_job_end(Printer->jobid);
+ print_job_end(Printer->jobid,True);
/* error codes unhandled so far ... */
return 0x0;
@@ -4239,21 +4262,12 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
/* we have a valid devmode
convert it and link it*/
- /*
- * Ensure printer->info_2->devmode is a valid pointer
- * as we will be overwriting it in convert_devicemode().
- */
-
- if (printer->info_2->devmode == NULL)
- printer->info_2->devmode = construct_nt_devicemode(printer->info_2->printername);
-
DEBUGADD(8,("Converting the devicemode struct\n"));
- convert_devicemode(devmode, printer->info_2->devmode);
-
- } else {
- if (printer->info_2->devmode != NULL)
- free_nt_devicemode(&printer->info_2->devmode);
- printer->info_2->devmode=NULL;
+ if (!convert_devicemode(printer->info_2->printername, devmode,
+ &printer->info_2->devmode)) {
+ result = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
}
/* Do sanity check on the requested changes for Samba */
@@ -5682,10 +5696,10 @@ uint32 _spoolss_setprinterdata( POLICY_HND *handle,
convert_specific_param(&param, value , type, data, real_len);
- /* Check if we are making any changes or not. Return true if
+ /* Check if we are making any changes or not. Return true if
nothing is actually changing. */
-
- ZERO_STRUCT(old_param);
+
+ ZERO_STRUCT(old_param);
if (get_specific_param(*printer, 2, param->value, &old_param.data,
&old_param.type, (unsigned int *)&old_param.data_len)) {
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 62194f73a5c..87bd3133276 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -116,8 +116,8 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
if (close_filestruct(fsp) == -1)
err1 = -1;
- if (normal_close && fsp->print_file) {
- print_fsp_end(fsp);
+ if (fsp->print_file) {
+ print_fsp_end(fsp, normal_close);
file_free(fsp);
return 0;
}
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index e443275d564..70a0c95b38c 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -736,7 +736,7 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
PACKI(desc,"W",5); /* pad1 */
PACKS(desc,"z",""); /* pszSepFile */
PACKS(desc,"z","WinPrint"); /* pszPrProc */
- PACKS(desc,"z",""); /* pszParms */
+ PACKS(desc,"z",NULL); /* pszParms */
PACKS(desc,"z",NULL); /* pszComment - don't ask.... JRA */
if (!status) {
PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 1fb7d2f4114..7413176967c 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -651,6 +651,11 @@ static void usage(char *pname)
BlockSignals(True,SIGUSR2);
#endif
+ /* POSIX demands that signals are inherited. If the invoking process has
+ * these signals masked, we will have problems, as we won't recieve them. */
+ BlockSignals(False, SIGHUP);
+ BlockSignals(False, SIGUSR1);
+
/* we want total control over the permissions on created files,
so set our umask to 0 */
umask(0);
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index 5bf81c8c41a..39d061b0a84 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -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/source/tdb/tdbtool.c b/source/tdb/tdbtool.c
index 508adc5d549..1b038226d02 100644
--- a/source/tdb/tdbtool.c
+++ b/source/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();
}