diff options
-rw-r--r-- | source/include/proto.h | 8 | ||||
-rw-r--r-- | source/nmbd/nmbd.c | 6 | ||||
-rw-r--r-- | source/printing/nt_printing.c | 89 | ||||
-rw-r--r-- | source/printing/printfsp.c | 4 | ||||
-rw-r--r-- | source/printing/printing.c | 13 | ||||
-rw-r--r-- | source/rpc_server/srv_spoolss_nt.c | 118 | ||||
-rw-r--r-- | source/smbd/close.c | 4 | ||||
-rw-r--r-- | source/smbd/lanman.c | 2 | ||||
-rw-r--r-- | source/smbd/server.c | 5 | ||||
-rw-r--r-- | source/tdb/tdb.c | 26 | ||||
-rw-r--r-- | source/tdb/tdbtool.c | 83 |
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, ¤t_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(¶m, 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(); } |