diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libsmb/clientgen.c | 5 | ||||
-rw-r--r-- | source3/libsmb/clilist.c | 15 | ||||
-rw-r--r-- | source3/libsmb/libsmbclient.c | 32 |
3 files changed, 41 insertions, 11 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4608d40d46..3a84a5bd4d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -79,7 +79,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { - extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -107,9 +106,9 @@ BOOL cli_receive_smb(struct cli_state *cli) } /* If the server is not responding, note that now */ - if (!ret) { - cli->smb_rw_error = smb_read_error; + DEBUG(0, ("Receiving SMB: Server stopped responding\n")); + cli->smb_rw_error = READ_TIMEOUT; close(cli->fd); cli->fd = -1; return ret; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 18c058f9df..22cb5930c2 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -349,10 +349,17 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mnt = cli_cm_get_mntpoint( cli ); - for (p=dirlist,i=0;i<total_received;i++) { - p += interpret_long_filename(cli,info_level,p,&finfo,NULL,NULL,NULL); - fn( mnt,&finfo, Mask, state ); - } + /* see if the server disconnected or the connection otherwise failed */ + if (cli_is_error(cli)) { + total_received = -1; + } else { + /* no connection problem. let user function add each entry */ + for (p=dirlist,i=0;i<total_received;i++) { + p += interpret_long_filename(cli, info_level, p, + &finfo,NULL,NULL,NULL); + fn( mnt,&finfo, Mask, state ); + } + } /* free up the dirlist buffer and last name raw blob */ SAFE_FREE(dirlist); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c74e18b13c..101cc02211 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2540,6 +2540,7 @@ static SMBCFILE * smbc_opendir_ctx(SMBCCTX *context, const char *fname) { + int saved_errno; fstring server, share, user, password, options; pstring workgroup; pstring path; @@ -2547,6 +2548,7 @@ smbc_opendir_ctx(SMBCCTX *context, char *p; SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; + struct _smbc_callbacks *cb; struct in_addr rem_ip; if (!context || !context->internal || @@ -2908,9 +2910,9 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } - errno = smbc_errno(context, targetcli); + saved_errno = smbc_errno(context, targetcli); - if (errno == EINVAL) { + if (saved_errno == EINVAL) { /* * See if they asked to opendir something * other than a directory. If so, the @@ -2926,12 +2928,34 @@ smbc_opendir_ctx(SMBCCTX *context, ! IS_DOS_DIR(mode)) { /* It is. Correct the error value */ - errno = ENOTDIR; + saved_errno = ENOTDIR; } } - return NULL; + /* + * If there was an error and the server is no + * good any more... + */ + cb = &context->callbacks; + if (cli_is_error(targetcli) && + cb->check_server_fn(context, srv)) { + + /* ... then remove it. */ + if (cb->remove_unused_server_fn(context, + srv)) { + /* + * We could not remove the server + * completely, remove it from the + * cache so we will not get it + * again. It will be removed when the + * last file/dir is closed. + */ + cb->remove_cached_srv_fn(context, srv); + } + } + errno = saved_errno; + return NULL; } } |