Index: libsmb/clidfs.c =================================================================== --- libsmb/clidfs.c (revision 15707) +++ libsmb/clidfs.c (working copy) @@ -57,8 +57,9 @@ struct in_addr ip; pstring servicename; char *sharename; - fstring newserver, newshare; - + fstring newserver = ""; + fstring newshare = ""; + /* make a copy so we don't modify the global string 'service' */ pstrcpy(servicename, share); sharename = servicename; @@ -257,6 +258,11 @@ return NULL; } +/******************************************************************** + Just to minimize patch size. +********************************************************************/ +static void clean_path( pstring clean, const char *path ); + /**************************************************************************** open a client connection to a \\server\share. Set's the current *cli global variable as a side-effect (but only if the connection is successful). @@ -354,19 +360,29 @@ /******************************************************************** split a dfs path into the server and share name components + assume + nodepath = //AAA/BBB/CCC/DDD + previous (wrong?) behavior + server = AAA/BBB/CCC + share = DDD + current behavior: + server = AAA + share = BBB ********************************************************************/ static void split_dfs_path( const char *nodepath, fstring server, fstring share ) { char *p; + char *p1; pstring path; + DEBUG(3,("split_dfs_path: nodepath=%s\n", nodepath )); pstrcpy( path, nodepath ); if ( path[0] != '\\' ) return; - p = strrchr_m( path, '\\' ); + p = strchr_m( (char *)&path[1], '\\' ); if ( !p ) return; @@ -374,6 +390,13 @@ *p = '\0'; p++; + p1 = p; + p1 = strchr_m( p, '\\' ); + + if( p1 ) { + *p1 = '\0'; + } + fstrcpy( share, p ); fstrcpy( server, &path[1] ); } @@ -575,13 +598,14 @@ uint16 consumed; struct cli_state *cli_ipc; pstring fullpath, cleanpath; - int pathlen; fstring server, share; struct cli_state *newcli; pstring newpath; pstring newmount; +#if 0 char *ppath; - + int pathlen; +#endif SMB_STRUCT_STAT sbuf; uint32 attributes; @@ -589,6 +613,7 @@ return False; *targetcli = NULL; + targetpath[0] = '\0'; /* send a trans2_query_path_info to check for a referral */ @@ -626,20 +651,25 @@ { return False; } - + +#if 0 /* just store the first referral for now Make sure to recreate the original string including any wildcards */ - - cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); - pathlen = strlen( fullpath )*2; - consumed = MIN(pathlen, consumed ); - pstrcpy( targetpath, &fullpath[consumed/2] ); + cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); + pathlen = strlen( fullpath )*2; + consumed = MIN(pathlen, consumed ); + pstrcpy( targetpath, &fullpath[consumed/2] ); + DEBUG(3,("cli_resolve_path: ** PRE ** targetpath=%s\n", targetpath )); +#endif + split_dfs_path( refs[0].dfspath, server, share ); SAFE_FREE( refs ); /* open the connection to the target path */ + DEBUG(3,("cli_resolve_path: Opening connection to TARGET path server=%s,share=%s\n", server, share )); + if ( (*targetcli = cli_cm_open(server, share, False)) == NULL ) { d_printf("Unable to follow dfs referral [//%s/%s]\n", server, share ); @@ -647,29 +677,67 @@ return False; } + +#if 0 /* parse out the consumed mount path */ /* trim off the \server\share\ */ + DEBUG(3,("cli_resolve_path: ** fullpath=%s\n", fullpath )); + fullpath[consumed/2] = '\0'; dos_clean_name( fullpath ); ppath = strchr_m( fullpath, '\\' ); ppath = strchr_m( ppath+1, '\\' ); ppath = strchr_m( ppath+1, '\\' ); ppath++; - - pstr_sprintf( newmount, "%s\\%s", mountpt, ppath ); + + if( ppath ) { + DEBUG(3,("cli_resolve_path: ** ppath=%s\n", ppath )); + } +#endif + + /* newmount should be kept empty... don't ask me why... + otherwise connection to share fails... */ + + newmount[0] = '\0'; + + /* targetpath should be changed to place we want to go + seems previous idea was to construct targetpath as concatenation + of ppath and ** PRE ** targetpath... + may be to point an initial directory... don't know... */ + + pstr_sprintf( targetpath, "%s", path ); + + /* just to be nice ... and not pass crap to function called... */ + + newpath[0] = '\0'; + cli_cm_set_mntpoint( *targetcli, newmount ); + DEBUG(3,("cli_resolve_path: ** targetpath=%s\n", targetpath )); + /* check for another dfs referral, note that we are not checking for loops here */ if ( !strequal( targetpath, "\\" ) ) { + DEBUG(3,("cli_resolve_path: making RECURSIVE call newmount=%s,targetpath=%s,newpath=%s\n", + newmount, targetpath, newpath )); if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) { *targetcli = newcli; pstrcpy( targetpath, newpath ); } } + /* seems it's needed to make 'dir' command work.... */ + + if( path[strlen(path)-1] == '*' ) { + pstrcat(targetpath,"*"); + } + + DEBUG(3,("cli_resolve_path: *** OUT *** path=%s, strlen(path)=%d\n", path, strlen(path) )); + DEBUG(3,("cli_resolve_path: *** OUT *** (*targetcli)->desthost=%s,(*targetcli)->share=%s, targetpath=%s\n", + (*targetcli)->desthost, (*targetcli)->share, targetpath )); + return True; }