On Mon, May 30, 2005 at 05:09:15PM +0200, Mair Wolfgang-awm013 wrote:
> Hello,
>
> I'm having problems with using smbclient on a win2k share. The server runs
> samba 3.0.14a on Solaris 9.
>
> I want to tar the whole directory of a share. Into a file on the server
>
> What I found out so far is, that it works until a maximum file count of 35.
> It is not size dependant but if the file count in that share exceeds more
> than 35 the smbclient hangs for ever and with the time is consuming up all
> the available memory. Until the server hangs as well due to a lack of memory
> space.
>
> Any ideas would be greatly appreciated.
This is probably the "infinate spin" reading directories
bug which we've fixed in SVN. Try this patch for 3.0.14a.
Jeremy
--- libsmb/clilist.c.orig 2005-04-13 23:14:24.000000000 -0700
+++ libsmb/clilist.c 2005-05-31 16:18:33.603556265 -0700
@@ -22,6 +22,8 @@
#include "includes.h"
+extern file_info def_finfo;
+
/****************************************************************************
Interpret a long filename structure - this is mostly guesses at the moment.
The length of the structure is returned
@@ -29,16 +31,20 @@
by NT and 2 is used by OS/2
****************************************************************************/
-static size_t interpret_long_filename(struct cli_state *cli,
- int level,char *p,file_info *finfo)
+static size_t interpret_long_filename(struct cli_state *cli, int level,char
*p,file_info *finfo,
+ uint32 *p_resume_key, DATA_BLOB
*p_last_name_raw, uint32 *p_last_name_raw_len)
{
- extern file_info def_finfo;
file_info finfo2;
int len;
char *base = p;
- if (!finfo) finfo = &finfo2;
+ if (!finfo) {
+ finfo = &finfo2;
+ }
+ if (p_resume_key) {
+ *p_resume_key = 0;
+ }
memcpy(finfo,&def_finfo,sizeof(*finfo));
switch (level) {
@@ -84,6 +90,10 @@
{
size_t namelen, slen;
p += 4; /* next entry offset */
+
+ if (p_resume_key) {
+ *p_resume_key = IVAL(p,0);
+ }
p += 4; /* fileindex */
/* these dates appear to arrive in a
@@ -130,6 +140,22 @@
clistr_pull(cli, finfo->name, p,
sizeof(finfo->name),
namelen, 0);
+
+ /* To be robust in the face of unicode conversion
failures
+ we need to copy the raw bytes of the last name seen
here.
+ Namelen doesn't include the terminating unicode
null, so
+ copy it here. */
+
+ if (p_last_name_raw && p_last_name_raw_len) {
+ if (namelen + 2 > p_last_name_raw->length) {
+ memset(p_last_name_raw->data, '\0',
sizeof(p_last_name_raw->length));
+ *p_last_name_raw_len = 0;
+ } else {
+ memcpy(p_last_name_raw->data, p,
namelen);
+ SSVAL(p_last_name_raw->data, namelen,
0);
+ *p_last_name_raw_len = namelen + 2;
+ }
+ }
return (size_t)IVAL(base, 0);
}
}
@@ -145,7 +171,7 @@
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
void (*fn)(const char *, file_info *, const char *, void *),
void *state)
{
-#if 0
+#if 1
int max_matches = 1366; /* Match W2k - was 512. */
#else
int max_matches = 512;
@@ -169,6 +195,9 @@
uint16 setup;
pstring param;
const char *mnt;
+ uint32 resume_key = 0;
+ uint32 last_name_raw_len = 0;
+ DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring));
/* NT uses 260, OS/2 uses 2. Both accept 1. */
info_level = (cli->capabilities&CAP_NT_SMBS)?260:1;
@@ -203,13 +232,19 @@
SSVAL(param,0,ff_dir_handle);
SSVAL(param,2,max_matches); /* max count */
SSVAL(param,4,info_level);
- SIVAL(param,6,0); /* ff_resume_key */
+ /* For W2K servers serving out FAT filesystems we
*must* set the
+ resume key. If it's not FAT then it's returned as
zero. */
+ SIVAL(param,6,resume_key); /* ff_resume_key */
/* NB. *DON'T* use continue here. If you do it seems
that W2K and bretheren
can miss filenames. Use last filename continue
instead. JRA */
SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END));
/* resume required + close on end */
p = param+12;
- p += clistr_push(cli, param+12, mask, sizeof(param)-12,
- STR_TERMINATE);
+ if (last_name_raw_len && (last_name_raw_len <
(sizeof(param)-12))) {
+ memcpy(p, last_name_raw.data,
last_name_raw_len);
+ p += last_name_raw_len;
+ } else {
+ p += clistr_push(cli, param+12, mask,
sizeof(param)-12, STR_TERMINATE);
+ }
}
param_len = PTR_DIFF(p, param);
@@ -276,7 +311,8 @@
/* Last entry - fixup the last offset length. */
SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));
}
- p2 += interpret_long_filename(cli,info_level,p2,&finfo);
+ p2 += interpret_long_filename(cli,info_level,p2,&finfo,
+
&resume_key,&last_name_raw,&last_name_raw_len);
}
if (ff_lastname > 0) {
@@ -316,12 +352,13 @@
mnt = cli_cm_get_mntpoint( cli );
for (p=dirlist,i=0;i<total_received;i++) {
- p += interpret_long_filename(cli,info_level,p,&finfo);
+ p +=
interpret_long_filename(cli,info_level,p,&finfo,NULL,NULL,NULL);
fn( mnt,&finfo, Mask, state );
}
- /* free up the dirlist buffer */
+ /* free up the dirlist buffer and last name raw blob */
SAFE_FREE(dirlist);
+ data_blob_free(&last_name_raw);
return(total_received);
}
@@ -332,7 +369,6 @@
static int interpret_short_filename(struct cli_state *cli, char *p,file_info
*finfo)
{
- extern file_info def_finfo;
*finfo = def_finfo;
--
To unsubscribe from this list go to the following URL and read the
instructions: https://lists.samba.org/mailman/listinfo/samba