commit b520befe6f51644d20434add9864d7a2fa30aa2e
[kai/samba.git] / source3 / libsmb / libsmb_dir.c
index 1486097d5125a10b8623cdbdfa2ca2d209dab0d7..770014b6f62350632a16fef274bdf37277ea4572 100644 (file)
@@ -1,23 +1,23 @@
-/* 
+/*
    Unix SMB/Netbios implementation.
    SMB client library implementation
    Copyright (C) Andrew Tridgell 1998
    Copyright (C) Richard Sharpe 2000, 2002
    Copyright (C) John Terpstra 2000
-   Copyright (C) Tom Jansen (Ninja ISD) 2002 
+   Copyright (C) Tom Jansen (Ninja ISD) 2002
    Copyright (C) Derrell Lipman 2003-2008
    Copyright (C) Jeremy Allison 2007, 2008
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -36,19 +36,19 @@ static void
 remove_dir(SMBCFILE *dir)
 {
        struct smbc_dir_list *d,*f;
-        
+
        d = dir->dir_list;
        while (d) {
-                
+
                f = d; d = d->next;
-                
+
                SAFE_FREE(f->dirent);
                SAFE_FREE(f);
-                
+
        }
-        
+
        dir->dir_list = dir->dir_end = dir->dir_next = NULL;
-        
+
 }
 
 static int
@@ -61,63 +61,63 @@ add_dirent(SMBCFILE *dir,
        int size;
         int name_length = (name == NULL ? 0 : strlen(name));
         int comment_len = (comment == NULL ? 0 : strlen(comment));
-        
+
        /*
-        * Allocate space for the dirent, which must be increased by the 
+        * Allocate space for the dirent, which must be increased by the
         * size of the name and the comment and 1 each for the null terminator.
         */
-        
+
        size = sizeof(struct smbc_dirent) + name_length + comment_len + 2;
-        
+
        dirent = (struct smbc_dirent *)SMB_MALLOC(size);
-        
+
        if (!dirent) {
-                
+
                dir->dir_error = ENOMEM;
                return -1;
-                
+
        }
-        
+
        ZERO_STRUCTP(dirent);
-        
+
        if (dir->dir_list == NULL) {
-                
+
                dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list);
                if (!dir->dir_list) {
-                        
+
                        SAFE_FREE(dirent);
                        dir->dir_error = ENOMEM;
                        return -1;
-                        
+
                }
                ZERO_STRUCTP(dir->dir_list);
-                
+
                dir->dir_end = dir->dir_next = dir->dir_list;
        }
        else {
-                
+
                dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list);
-                
+
                if (!dir->dir_end->next) {
-                        
+
                        SAFE_FREE(dirent);
                        dir->dir_error = ENOMEM;
                        return -1;
-                        
+
                }
                ZERO_STRUCTP(dir->dir_end->next);
-                
+
                dir->dir_end = dir->dir_end->next;
        }
-        
+
        dir->dir_end->next = NULL;
        dir->dir_end->dirent = dirent;
-        
+
        dirent->smbc_type = type;
        dirent->namelen = name_length;
        dirent->commentlen = comment_len;
        dirent->dirlen = size;
-        
+
         /*
          * dirent->namelen + 1 includes the null (no null termination needed)
          * Ditto for dirent->commentlen.
@@ -126,9 +126,9 @@ add_dirent(SMBCFILE *dir,
        strncpy(dirent->name, (name?name:""), dirent->namelen + 1);
        dirent->comment = (char *)(&dirent->name + dirent->namelen + 1);
        strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1);
-        
+
        return 0;
-        
+
 }
 
 static void
@@ -142,18 +142,18 @@ list_unique_wg_fn(const char *name,
         struct smbc_dirent *dirent;
        int dirent_type;
         int do_remove = 0;
-        
+
        dirent_type = dir->dir_type;
-        
+
        if (add_dirent(dir, name, comment, dirent_type) < 0) {
-                
+
                /* An error occurred, what do we do? */
                /* FIXME: Add some code here */
        }
-        
+
         /* Point to the one just added */
         dirent = dir->dir_end->dirent;
-        
+
         /* See if this was a duplicate */
         for (dir_list = dir->dir_list;
              dir_list != dir->dir_end;
@@ -163,7 +163,7 @@ list_unique_wg_fn(const char *name,
                         /* Duplicate.  End end of list need to be removed. */
                         do_remove = 1;
                 }
-                
+
                 if (do_remove && dir_list->next == dir->dir_end) {
                         /* Found the end of the list.  Remove it. */
                         dir->dir_end = dir_list;
@@ -183,7 +183,7 @@ list_fn(const char *name,
 {
        SMBCFILE *dir = (SMBCFILE *)state;
        int dirent_type;
-        
+
        /*
          * We need to process the type a little ...
          *
@@ -195,27 +195,27 @@ list_fn(const char *name,
          * administrative shares:
          * ADMIN$, IPC$, C$, D$, E$ ...  are type |= 0x80000000
          */
-        
+
        if (dir->dir_type == SMBC_FILE_SHARE) {
                switch (type) {
                 case 0 | 0x80000000:
                case 0:
                        dirent_type = SMBC_FILE_SHARE;
                        break;
-                        
+
                case 1:
                        dirent_type = SMBC_PRINTER_SHARE;
                        break;
-                        
+
                case 2:
                        dirent_type = SMBC_COMMS_SHARE;
                        break;
-                        
+
                 case 3 | 0x80000000:
                case 3:
                        dirent_type = SMBC_IPC_SHARE;
                        break;
-                        
+
                default:
                        dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */
                        break;
@@ -224,12 +224,12 @@ list_fn(const char *name,
        else {
                 dirent_type = dir->dir_type;
         }
-        
+
        if (add_dirent(dir, name, comment, dirent_type) < 0) {
-                
+
                /* An error occurred, what do we do? */
                /* FIXME: Add some code here */
-                
+
        }
 }
 
@@ -239,16 +239,16 @@ dir_list_fn(const char *mnt,
             const char *mask,
             void *state)
 {
-        
-       if (add_dirent((SMBCFILE *)state, finfo->name, "", 
+
+       if (add_dirent((SMBCFILE *)state, finfo->name, "",
                       (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) {
-                
+
                /* Handle an error ... */
-                
+
                /* FIXME: Add some code ... */
-                
-       } 
-        
+
+       }
+
 }
 
 static int
@@ -261,60 +261,67 @@ net_share_enum_rpc(struct cli_state *cli,
 {
         int i;
        WERROR result;
-       ENUM_HND enum_hnd;
-        uint32 info_level = 1;
        uint32 preferred_len = 0xffffffff;
         uint32 type;
-       SRV_SHARE_INFO_CTR ctr;
+       struct srvsvc_NetShareInfoCtr info_ctr;
+       struct srvsvc_NetShareCtr1 ctr1;
        fstring name = "";
         fstring comment = "";
        struct rpc_pipe_client *pipe_hnd;
         NTSTATUS nt_status;
-        
+       uint32_t resume_handle = 0;
+       uint32_t total_entries = 0;
+
         /* Open the server service pipe */
-        pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status);
-        if (!pipe_hnd) {
+        nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc.syntax_id,
+                                            &pipe_hnd);
+        if (!NT_STATUS_IS_OK(nt_status)) {
                 DEBUG(1, ("net_share_enum_rpc pipe open fail!\n"));
                 return -1;
         }
-        
+
+       ZERO_STRUCT(info_ctr);
+       ZERO_STRUCT(ctr1);
+
+       info_ctr.level = 1;
+       info_ctr.ctr.ctr1 = &ctr1;
+
         /* Issue the NetShareEnum RPC call and retrieve the response */
-       init_enum_hnd(&enum_hnd, 0);
-       result = rpccli_srvsvc_net_share_enum(pipe_hnd,
-                                              talloc_tos(),
-                                              info_level,
-                                              &ctr,
-                                              preferred_len,
-                                              &enum_hnd);
-        
+       nt_status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, talloc_tos(),
+                                                 pipe_hnd->desthost,
+                                                 &info_ctr,
+                                                 preferred_len,
+                                                 &total_entries,
+                                                 &resume_handle,
+                                                 &result);
+
         /* Was it successful? */
-       if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) {
+       if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result) ||
+           total_entries == 0) {
                 /*  Nope.  Go clean up. */
                goto done;
         }
-        
+
         /* For each returned entry... */
-        for (i = 0; i < ctr.num_entries; i++) {
-                
+        for (i = 0; i < total_entries; i++) {
+
                 /* pull out the share name */
-                rpcstr_pull_unistr2_fstring(
-                        name, &ctr.share.info1[i].info_1_str.uni_netname);
-                
+               fstrcpy(name, info_ctr.ctr.ctr1->array[i].name);
+
                 /* pull out the share's comment */
-                rpcstr_pull_unistr2_fstring(
-                        comment, &ctr.share.info1[i].info_1_str.uni_remark);
-                
+               fstrcpy(comment, info_ctr.ctr.ctr1->array[i].comment);
+
                 /* Get the type value */
-                type = ctr.share.info1[i].info_1.type;
-                
+                type = info_ctr.ctr.ctr1->array[i].type;
+
                 /* Add this share to the list */
                 (*fn)(name, type, comment, state);
         }
-        
+
 done:
         /* Close the server service pipe */
-        cli_rpc_pipe_close(pipe_hnd);
-        
+        TALLOC_FREE(pipe_hnd);
+
         /* Tell 'em if it worked */
         return W_ERROR_IS_OK(result) ? 0 : -1;
 }
@@ -332,10 +339,10 @@ SMBC_check_options(char *server,
         DEBUG(4, ("SMBC_check_options(): server='%s' share='%s' "
                   "path='%s' options='%s'\n",
                   server, share, path, options));
-        
+
         /* No options at all is always ok */
         if (! *options) return 0;
-        
+
         /* Currently, we don't support any options. */
         return -1;
 }
@@ -359,22 +366,22 @@ SMBC_opendir_ctx(SMBCCTX *context,
        SMBCFILE *dir = NULL;
        struct sockaddr_storage rem_ss;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
                DEBUG(4, ("no valid context\n"));
                errno = EINVAL + 8192;
                TALLOC_FREE(frame);
                return NULL;
-                
+
        }
-        
+
        if (!fname) {
                DEBUG(4, ("no valid fname\n"));
                errno = EINVAL + 8193;
                TALLOC_FREE(frame);
                return NULL;
        }
-        
+
        if (SMBC_parse_path(frame,
                             context,
                             fname,
@@ -390,11 +397,11 @@ SMBC_opendir_ctx(SMBCCTX *context,
                TALLOC_FREE(frame);
                return NULL;
        }
-        
+
        DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' "
                   "path='%s' options='%s'\n",
                   fname, server, share, path, options));
-        
+
         /* Ensure the options are valid */
         if (SMBC_check_options(server, share, path, options)) {
                 DEBUG(4, ("unacceptable options (%s)\n", options));
@@ -402,7 +409,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                TALLOC_FREE(frame);
                 return NULL;
         }
-        
+
        if (!user || user[0] == (char)0) {
                user = talloc_strdup(frame, smbc_getUser(context));
                if (!user) {
@@ -411,35 +418,35 @@ SMBC_opendir_ctx(SMBCCTX *context,
                        return NULL;
                }
        }
-        
+
        dir = SMB_MALLOC_P(SMBCFILE);
-        
+
        if (!dir) {
                errno = ENOMEM;
                TALLOC_FREE(frame);
                return NULL;
        }
-        
+
        ZERO_STRUCTP(dir);
-        
+
        dir->cli_fd   = 0;
        dir->fname    = SMB_STRDUP(fname);
        dir->srv      = NULL;
        dir->offset   = 0;
        dir->file     = False;
        dir->dir_list = dir->dir_next = dir->dir_end = NULL;
-        
+
        if (server[0] == (char)0) {
-                
+
                 int i;
                 int count;
                 int max_lmb_count;
                 struct ip_service *ip_list;
                 struct ip_service server_addr;
                 struct user_auth_info u_info;
-                
+
                if (share[0] != (char)0 || path[0] != (char)0) {
-                        
+
                        errno = EINVAL + 8196;
                        if (dir) {
                                SAFE_FREE(dir->fname);
@@ -448,12 +455,12 @@ SMBC_opendir_ctx(SMBCCTX *context,
                        TALLOC_FREE(frame);
                        return NULL;
                }
-                
+
                 /* Determine how many local master browsers to query */
                 max_lmb_count = (smbc_getOptionBrowseMaxLmbCount(context) == 0
                                  ? INT_MAX
                                  : smbc_getOptionBrowseMaxLmbCount(context));
-                
+
                memset(&u_info, '\0', sizeof(u_info));
                u_info.username = talloc_strdup(frame,user);
                u_info.password = talloc_strdup(frame,password);
@@ -465,7 +472,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                        TALLOC_FREE(frame);
                        return NULL;
                }
-                
+
                /*
                  * We have server and share and path empty but options
                  * requesting that we scan all master browsers for their list
@@ -474,16 +481,16 @@ SMBC_opendir_ctx(SMBCCTX *context,
                  * doesn't work, then try our other methods which return only
                  * a single master browser.
                  */
-                
+
                 ip_list = NULL;
                 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
                                                         &count)))
                {
-                        
+
                         SAFE_FREE(ip_list);
-                        
+
                         if (!find_master_ip(workgroup, &server_addr.ss)) {
-                                
+
                                if (dir) {
                                        SAFE_FREE(dir->fname);
                                        SAFE_FREE(dir);
@@ -492,7 +499,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                TALLOC_FREE(frame);
                                 return NULL;
                         }
-                        
+
                        ip_list = (struct ip_service *)memdup(
                                &server_addr, sizeof(server_addr));
                        if (ip_list == NULL) {
@@ -502,17 +509,17 @@ SMBC_opendir_ctx(SMBCCTX *context,
                        }
                         count = 1;
                 }
-                
+
                 for (i = 0; i < count && i < max_lmb_count; i++) {
                        char addr[INET6_ADDRSTRLEN];
                        char *wg_ptr = NULL;
                        struct cli_state *cli = NULL;
-                        
+
                        print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
                         DEBUG(99, ("Found master browser %d of %d: %s\n",
                                    i+1, MAX(count, max_lmb_count),
                                    addr));
-                        
+
                         cli = get_ipc_connect_master_ip(talloc_tos(),
                                                        &ip_list[i],
                                                         &u_info,
@@ -522,39 +529,39 @@ SMBC_opendir_ctx(SMBCCTX *context,
                        if (!cli) {
                                continue;
                        }
-                        
+
                        workgroup = talloc_strdup(frame, wg_ptr);
                        server = talloc_strdup(frame, cli->desthost);
-                        
+
                         cli_shutdown(cli);
-                        
+
                        if (!workgroup || !server) {
                                errno = ENOMEM;
                                TALLOC_FREE(frame);
                                return NULL;
                        }
-                        
+
                         DEBUG(4, ("using workgroup %s %s\n",
                                   workgroup, server));
-                        
+
                         /*
                          * For each returned master browser IP address, get a
                          * connection to IPC$ on the server if we do not
                          * already have one, and determine the
                          * workgroups/domains that it knows about.
                          */
-                        
+
                         srv = SMBC_server(frame, context, True, server, "IPC$",
                                           &workgroup, &user, &password);
                         if (!srv) {
                                 continue;
                         }
-                        
+
                         dir->srv = srv;
                         dir->dir_type = SMBC_WORKGROUP;
-                        
+
                         /* Now, list the stuff ... */
-                        
+
                         if (!cli_NetServerEnum(srv->cli,
                                                workgroup,
                                                SV_TYPE_DOMAIN_ENUM,
@@ -563,7 +570,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                 continue;
                         }
                 }
-                
+
                 SAFE_FREE(ip_list);
         } else {
                 /*
@@ -572,7 +579,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                  */
                if (*share == '\0') {
                        if (*path != '\0') {
-                                
+
                                 /* Should not have empty share with path */
                                errno = EINVAL + 8197;
                                if (dir) {
@@ -581,9 +588,9 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                }
                                TALLOC_FREE(frame);
                                return NULL;
-                                
+
                        }
-                        
+
                        /*
                          * We don't know if <server> is really a server name
                          * or is a workgroup/domain name.  If we already have
@@ -592,7 +599,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                          * <server><1B>, or <server><20> translates.  We check
                          * to see if <server> is an IP address first.
                          */
-                        
+
                         /*
                          * See if we have an existing server.  Do not
                          * establish a connection if one does not already
@@ -601,7 +608,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                         srv = SMBC_server(frame, context, False,
                                           server, "IPC$",
                                           &workgroup, &user, &password);
-                        
+
                         /*
                          * If no existing server and not an IP addr, look for
                          * LMB or DMB
@@ -610,17 +617,17 @@ SMBC_opendir_ctx(SMBCCTX *context,
                             !is_ipaddress(server) &&
                            (resolve_name(server, &rem_ss, 0x1d) ||   /* LMB */
                              resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */
-                                
+
                                fstring buserver;
-                                
+
                                dir->dir_type = SMBC_SERVER;
-                                
+
                                /*
                                 * Get the backup list ...
                                 */
                                if (!name_status_find(server, 0, 0,
                                                       &rem_ss, buserver)) {
-                                        
+
                                         DEBUG(0,("Could not get name of "
                                                  "local/domain master browser "
                                                  "for server %s\n", server));
@@ -631,9 +638,9 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                        errno = EPERM;
                                        TALLOC_FREE(frame);
                                        return NULL;
-                                        
+
                                }
-                                
+
                                /*
                                  * Get a connection to IPC$ on the server if
                                  * we do not already have one
@@ -650,16 +657,16 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                        }
                                        TALLOC_FREE(frame);
                                        return NULL;
-                                        
+
                                }
-                                
+
                                dir->srv = srv;
-                                
+
                                /* Now, list the servers ... */
                                if (!cli_NetServerEnum(srv->cli, server,
                                                        0x0000FFFE, list_fn,
                                                       (void *)dir)) {
-                                        
+
                                        if (dir) {
                                                SAFE_FREE(dir->fname);
                                                SAFE_FREE(dir);
@@ -669,7 +676,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                }
                        } else if (srv ||
                                    (resolve_name(server, &rem_ss, 0x20))) {
-                                
+
                                 /*
                                  * If we hadn't found the server, get one now
                                  */
@@ -679,7 +686,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                                           &workgroup,
                                                           &user, &password);
                                 }
-                                
+
                                 if (!srv) {
                                         if (dir) {
                                                 SAFE_FREE(dir->fname);
@@ -687,14 +694,14 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                         }
                                        TALLOC_FREE(frame);
                                         return NULL;
-                                        
+
                                 }
-                                
+
                                 dir->dir_type = SMBC_FILE_SHARE;
                                 dir->srv = srv;
-                                
+
                                 /* List the shares ... */
-                                
+
                                 if (net_share_enum_rpc(
                                             srv->cli,
                                             list_fn,
@@ -703,7 +710,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                             srv->cli,
                                             list_fn,
                                             (void *)dir) < 0) {
-                                        
+
                                         errno = cli_errno(srv->cli);
                                         if (dir) {
                                                 SAFE_FREE(dir->fname);
@@ -711,7 +718,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                         }
                                        TALLOC_FREE(frame);
                                         return NULL;
-                                        
+
                                 }
                         } else {
                                 /* Neither the workgroup nor server exists */
@@ -723,7 +730,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                TALLOC_FREE(frame);
                                 return NULL;
                        }
-                        
+
                }
                else {
                         /*
@@ -732,13 +739,13 @@ SMBC_opendir_ctx(SMBCCTX *context,
                          */
                        char *targetpath;
                        struct cli_state *targetcli;
-                        
+
                        /* We connect to the server and list the directory */
                        dir->dir_type = SMBC_FILE_SHARE;
-                        
+
                        srv = SMBC_server(frame, context, True, server, share,
                                           &workgroup, &user, &password);
-                        
+
                        if (!srv) {
                                if (dir) {
                                        SAFE_FREE(dir->fname);
@@ -747,11 +754,11 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                TALLOC_FREE(frame);
                                return NULL;
                        }
-                        
+
                        dir->srv = srv;
-                        
+
                        /* Now, list the files ... */
-                        
+
                         p = path + strlen(path);
                        path = talloc_asprintf_append(path, "\\*");
                        if (!path) {
@@ -762,7 +769,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                TALLOC_FREE(frame);
                                return NULL;
                        }
-                        
+
                        if (!cli_resolve_path(frame, "", srv->cli, path,
                                               &targetcli, &targetpath)) {
                                d_printf("Could not resolve %s\n", path);
@@ -773,17 +780,17 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                TALLOC_FREE(frame);
                                return NULL;
                        }
-                        
+
                        if (cli_list(targetcli, targetpath,
                                      aDIR | aSYSTEM | aHIDDEN,
                                      dir_list_fn, (void *)dir) < 0) {
-                                
+
                                if (dir) {
                                        SAFE_FREE(dir->fname);
                                        SAFE_FREE(dir);
                                }
                                saved_errno = SMBC_errno(context, targetcli);
-                                
+
                                 if (saved_errno == EINVAL) {
                                         /*
                                          * See if they asked to opendir
@@ -793,28 +800,28 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                          * than ENOTDIR.
                                          */
                                         *p = '\0'; /* restore original path */
-                                        
+
                                         if (SMBC_getatr(context, srv, path,
                                                         &mode, NULL,
                                                         NULL, NULL, NULL, NULL,
                                                         NULL) &&
                                             ! IS_DOS_DIR(mode)) {
-                                                
+
                                                 /* It is.  Correct the error value */
                                                 saved_errno = ENOTDIR;
                                         }
                                 }
-                                
+
                                 /*
                                  * If there was an error and the server is no
                                  * good any more...
                                  */
                                 if (cli_is_error(targetcli) &&
                                     smbc_getFunctionCheckServer(context)(context, srv)) {
-                                        
+
                                         /* ... then remove it. */
                                         if (smbc_getFunctionRemoveUnusedServer(context)(context,
-                                                                                        srv)) { 
+                                                                                        srv)) {
                                                 /*
                                                  * We could not remove the
                                                  * server completely, remove
@@ -826,19 +833,19 @@ SMBC_opendir_ctx(SMBCCTX *context,
                                                 smbc_getFunctionRemoveCachedServer(context)(context, srv);
                                         }
                                 }
-                                
+
                                 errno = saved_errno;
                                TALLOC_FREE(frame);
                                return NULL;
                        }
                }
-                
+
        }
-        
+
        DLIST_ADD(context->internal->files, dir);
        TALLOC_FREE(frame);
        return dir;
-        
+
 }
 
 /*
@@ -850,32 +857,32 @@ SMBC_closedir_ctx(SMBCCTX *context,
                   SMBCFILE *dir)
 {
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
                errno = EBADF;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        remove_dir(dir); /* Clean it up */
-        
+
        DLIST_REMOVE(context->internal->files, dir);
-        
+
        if (dir) {
-                
+
                SAFE_FREE(dir->fname);
                SAFE_FREE(dir);    /* Free the space too */
        }
-        
+
        TALLOC_FREE(frame);
        return 0;
-        
+
 }
 
 static void
@@ -885,33 +892,33 @@ smbc_readdir_internal(SMBCCTX * context,
                       int max_namebuf_len)
 {
         if (smbc_getOptionUrlEncodeReaddirEntries(context)) {
-                
+
                 /* url-encode the name.  get back remaining buffer space */
                 max_namebuf_len =
                         SMBC_urlencode(dest->name, src->name, max_namebuf_len);
-                
+
                 /* We now know the name length */
                 dest->namelen = strlen(dest->name);
-                
+
                 /* Save the pointer to the beginning of the comment */
                 dest->comment = dest->name + dest->namelen + 1;
-                
+
                 /* Copy the comment */
                 strncpy(dest->comment, src->comment, max_namebuf_len - 1);
                 dest->comment[max_namebuf_len - 1] = '\0';
-                
+
                 /* Save other fields */
                 dest->smbc_type = src->smbc_type;
                 dest->commentlen = strlen(dest->comment);
                 dest->dirlen = ((dest->comment + dest->commentlen + 1) -
                                 (char *) dest);
         } else {
-                
+
                 /* No encoding.  Just copy the entry as is. */
                 memcpy(dest, src, src->dirlen);
                 dest->comment = (char *)(&dest->name + src->namelen + 1);
         }
-        
+
 }
 
 /*
@@ -925,58 +932,57 @@ SMBC_readdir_ctx(SMBCCTX *context,
         int maxlen;
        struct smbc_dirent *dirp, *dirent;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        /* Check that all is ok first ... */
-        
+
        if (!context || !context->internal->initialized) {
-                
+
                errno = EINVAL;
                 DEBUG(0, ("Invalid context in SMBC_readdir_ctx()\n"));
                TALLOC_FREE(frame);
                return NULL;
-                
+
        }
-        
+
        if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
-                
+
                errno = EBADF;
                 DEBUG(0, ("Invalid dir in SMBC_readdir_ctx()\n"));
                TALLOC_FREE(frame);
                return NULL;
-                
+
        }
-        
+
        if (dir->file != False) { /* FIXME, should be dir, perhaps */
-                
+
                errno = ENOTDIR;
                 DEBUG(0, ("Found file vs directory in SMBC_readdir_ctx()\n"));
                TALLOC_FREE(frame);
                return NULL;
-                
+
        }
-        
+
        if (!dir->dir_next) {
                TALLOC_FREE(frame);
                return NULL;
         }
-        
+
         dirent = dir->dir_next->dirent;
         if (!dirent) {
-                
+
                 errno = ENOENT;
                TALLOC_FREE(frame);
                 return NULL;
-                
+
         }
-        
-        dirp = (struct smbc_dirent *)context->internal->dirent;
-        maxlen = (sizeof(context->internal->dirent) -
-                  sizeof(struct smbc_dirent));
-        
+
+        dirp = &context->internal->dirent;
+        maxlen = sizeof(context->internal->_dirent_name);
+
         smbc_readdir_internal(context, dirp, dirent, maxlen);
-        
+
         dir->dir_next = dir->dir_next->next;
-        
+
        TALLOC_FREE(frame);
         return dirp;
 }
@@ -997,99 +1003,98 @@ SMBC_getdents_ctx(SMBCCTX *context,
        char *ndir = (char *)dirp;
        struct smbc_dir_list *dirlist;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        /* Check that all is ok first ... */
-        
+
        if (!context || !context->internal->initialized) {
-                
+
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
-                
+
                errno = EBADF;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        if (dir->file != False) { /* FIXME, should be dir, perhaps */
-                
+
                errno = ENOTDIR;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
-       /* 
+
+       /*
         * Now, retrieve the number of entries that will fit in what was passed
-        * We have to figure out if the info is in the list, or we need to 
+        * We have to figure out if the info is in the list, or we need to
         * send a request to the server to get the info.
         */
-        
+
        while ((dirlist = dir->dir_next)) {
                struct smbc_dirent *dirent;
-                
+
                if (!dirlist->dirent) {
-                        
+
                        errno = ENOENT;  /* Bad error */
                        TALLOC_FREE(frame);
                        return -1;
-                        
+
                }
-                
+
                 /* Do urlencoding of next entry, if so selected */
-                dirent = (struct smbc_dirent *)context->internal->dirent;
-                maxlen = (sizeof(context->internal->dirent) -
-                          sizeof(struct smbc_dirent));
+                dirent = &context->internal->dirent;
+                maxlen = sizeof(context->internal->_dirent_name);
                 smbc_readdir_internal(context, dirent,
                                       dirlist->dirent, maxlen);
-                
+
                 reqd = dirent->dirlen;
-                
+
                if (rem < reqd) {
-                        
+
                        if (rem < count) { /* We managed to copy something */
-                                
+
                                errno = 0;
                                TALLOC_FREE(frame);
                                return count - rem;
-                                
+
                        }
                        else { /* Nothing copied ... */
-                                
+
                                errno = EINVAL;  /* Not enough space ... */
                                TALLOC_FREE(frame);
                                return -1;
-                                
+
                        }
-                        
+
                }
-                
+
                memcpy(ndir, dirent, reqd); /* Copy the data in ... */
-                
-               ((struct smbc_dirent *)ndir)->comment = 
+
+               ((struct smbc_dirent *)ndir)->comment =
                        (char *)(&((struct smbc_dirent *)ndir)->name +
                                  dirent->namelen +
                                  1);
-                
+
                ndir += reqd;
-                
+
                rem -= reqd;
-                
+
                dir->dir_next = dirlist = dirlist -> next;
        }
-        
+
        TALLOC_FREE(frame);
-        
+
        if (rem == count)
                return 0;
        else
                return count - rem;
-        
+
 }
 
 /*
@@ -1111,21 +1116,21 @@ SMBC_mkdir_ctx(SMBCCTX *context,
        char *targetpath = NULL;
        struct cli_state *targetcli = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        if (!fname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        DEBUG(4, ("smbc_mkdir(%s)\n", fname));
-        
+
        if (SMBC_parse_path(frame,
                             context,
                             fname,
@@ -1140,7 +1145,7 @@ SMBC_mkdir_ctx(SMBCCTX *context,
                TALLOC_FREE(frame);
                return -1;
         }
-        
+
        if (!user || user[0] == (char)0) {
                user = talloc_strdup(frame, smbc_getUser(context));
                if (!user) {
@@ -1149,17 +1154,17 @@ SMBC_mkdir_ctx(SMBCCTX *context,
                        return -1;
                }
        }
-        
+
        srv = SMBC_server(frame, context, True,
                           server, share, &workgroup, &user, &password);
-        
+
        if (!srv) {
-                
+
                TALLOC_FREE(frame);
                return -1;  /* errno set by SMBC_server */
-                
+
        }
-        
+
        /*d_printf(">>>mkdir: resolving %s\n", path);*/
        if (!cli_resolve_path(frame, "", srv->cli, path,
                               &targetcli, &targetpath)) {
@@ -1168,26 +1173,24 @@ SMBC_mkdir_ctx(SMBCCTX *context,
                return -1;
        }
        /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/
-        
+
        if (!cli_mkdir(targetcli, targetpath)) {
-                
+
                errno = SMBC_errno(context, targetcli);
                TALLOC_FREE(frame);
                return -1;
-                
-       } 
-        
+
+       }
+
        TALLOC_FREE(frame);
        return 0;
-        
+
 }
 
 /*
  * Our list function simply checks to see if a directory is not empty
  */
 
-static int smbc_rmdir_dirempty = True;
-
 static void
 rmdir_list_fn(const char *mnt,
               file_info *finfo,
@@ -1196,7 +1199,8 @@ rmdir_list_fn(const char *mnt,
 {
        if (strncmp(finfo->name, ".", 1) != 0 &&
             strncmp(finfo->name, "..", 2) != 0) {
-               smbc_rmdir_dirempty = False;
+               bool *smbc_rmdir_dirempty = (bool *)state;
+               *smbc_rmdir_dirempty = false;
         }
 }
 
@@ -1218,21 +1222,21 @@ SMBC_rmdir_ctx(SMBCCTX *context,
         char *targetpath = NULL;
        struct cli_state *targetcli = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        if (!fname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        DEBUG(4, ("smbc_rmdir(%s)\n", fname));
-        
+
        if (SMBC_parse_path(frame,
                             context,
                             fname,
@@ -1247,7 +1251,7 @@ SMBC_rmdir_ctx(SMBCCTX *context,
                TALLOC_FREE(frame);
                return -1;
         }
-        
+
        if (!user || user[0] == (char)0) {
                user = talloc_strdup(frame, smbc_getUser(context));
                if (!user) {
@@ -1256,17 +1260,17 @@ SMBC_rmdir_ctx(SMBCCTX *context,
                        return -1;
                }
        }
-        
+
        srv = SMBC_server(frame, context, True,
                           server, share, &workgroup, &user, &password);
-        
+
        if (!srv) {
-                
+
                TALLOC_FREE(frame);
                return -1;  /* errno set by SMBC_server */
-                
+
        }
-        
+
        /*d_printf(">>>rmdir: resolving %s\n", path);*/
        if (!cli_resolve_path(frame, "", srv->cli, path,
                               &targetcli, &targetpath)) {
@@ -1275,19 +1279,18 @@ SMBC_rmdir_ctx(SMBCCTX *context,
                return -1;
        }
        /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/
-        
-        
+
+
        if (!cli_rmdir(targetcli, targetpath)) {
-                
+
                errno = SMBC_errno(context, targetcli);
-                
+
                if (errno == EACCES) {  /* Check if the dir empty or not */
-                        
+
                         /* Local storage to avoid buffer overflows */
                        char *lpath;
-                        
-                       smbc_rmdir_dirempty = True;  /* Make this so ... */
-                        
+                       bool smbc_rmdir_dirempty = true;
+
                        lpath = talloc_asprintf(frame, "%s\\*",
                                                targetpath);
                        if (!lpath) {
@@ -1295,34 +1298,35 @@ SMBC_rmdir_ctx(SMBCCTX *context,
                                TALLOC_FREE(frame);
                                return -1;
                        }
-                        
+
                        if (cli_list(targetcli, lpath,
                                      aDIR | aSYSTEM | aHIDDEN,
-                                     rmdir_list_fn, NULL) < 0) {
-                                
+                                     rmdir_list_fn,
+                                    &smbc_rmdir_dirempty) < 0) {
+
                                /* Fix errno to ignore latest error ... */
                                DEBUG(5, ("smbc_rmdir: "
                                           "cli_list returned an error: %d\n",
                                          SMBC_errno(context, targetcli)));
                                errno = EACCES;
-                                
+
                        }
-                        
+
                        if (smbc_rmdir_dirempty)
                                errno = EACCES;
                        else
                                errno = ENOTEMPTY;
-                        
+
                }
-                
+
                TALLOC_FREE(frame);
                return -1;
-                
-       } 
-        
+
+       }
+
        TALLOC_FREE(frame);
        return 0;
-        
+
 }
 
 /*
@@ -1334,38 +1338,38 @@ SMBC_telldir_ctx(SMBCCTX *context,
                  SMBCFILE *dir)
 {
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
-                
+
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
-                
+
                errno = EBADF;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        if (dir->file != False) { /* FIXME, should be dir, perhaps */
-                
+
                errno = ENOTDIR;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
         /* See if we're already at the end. */
         if (dir->dir_next == NULL) {
                 /* We are. */
                TALLOC_FREE(frame);
                 return -1;
         }
-        
+
        /*
         * We return the pointer here as the offset
         */
@@ -1378,29 +1382,29 @@ SMBC_telldir_ctx(SMBCCTX *context,
  */
 
 static struct smbc_dir_list *
-check_dir_ent(struct smbc_dir_list *list, 
+check_dir_ent(struct smbc_dir_list *list,
               struct smbc_dirent *dirent)
 {
-        
+
        /* Run down the list looking for what we want */
-        
+
        if (dirent) {
-                
+
                struct smbc_dir_list *tmp = list;
-                
+
                while (tmp) {
-                        
+
                        if (tmp->dirent == dirent)
                                return tmp;
-                        
+
                        tmp = tmp->next;
-                        
+
                }
-                
+
        }
-        
+
        return NULL;  /* Not found, or an error */
-        
+
 }
 
 
@@ -1417,50 +1421,50 @@ SMBC_lseekdir_ctx(SMBCCTX *context,
        struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset;
        struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
-                
+
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        if (dir->file != False) { /* FIXME, should be dir, perhaps */
-                
+
                errno = ENOTDIR;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        /* Now, check what we were passed and see if it is OK ... */
-        
+
        if (dirent == NULL) {  /* Seek to the begining of the list */
-                
+
                dir->dir_next = dir->dir_list;
                TALLOC_FREE(frame);
                return 0;
-                
+
        }
-        
+
         if (offset == -1) {     /* Seek to the end of the list */
                 dir->dir_next = NULL;
                TALLOC_FREE(frame);
                 return 0;
         }
-        
+
        /* Now, run down the list and make sure that the entry is OK       */
        /* This may need to be changed if we change the format of the list */
-        
+
        if ((list_ent = check_dir_ent(dir->dir_list, dirent)) == NULL) {
                errno = EINVAL;   /* Bad entry */
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        dir->dir_next = list_ent;
-        
+
        TALLOC_FREE(frame);
        return 0;
 }
@@ -1474,13 +1478,13 @@ SMBC_fstatdir_ctx(SMBCCTX *context,
                   SMBCFILE *dir,
                   struct stat *st)
 {
-        
+
        if (!context || !context->internal->initialized) {
-                
+
                errno = EINVAL;
                return -1;
        }
-        
+
        /* No code yet ... */
        return 0;
 }
@@ -1499,22 +1503,22 @@ SMBC_chmod_ctx(SMBCCTX *context,
        char *path = NULL;
        uint16 mode;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
-                
+
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        if (!fname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode));
-        
+
        if (SMBC_parse_path(frame,
                             context,
                             fname,
@@ -1529,7 +1533,7 @@ SMBC_chmod_ctx(SMBCCTX *context,
                TALLOC_FREE(frame);
                return -1;
         }
-        
+
        if (!user || user[0] == (char)0) {
                user = talloc_strdup(frame, smbc_getUser(context));
                if (!user) {
@@ -1538,28 +1542,28 @@ SMBC_chmod_ctx(SMBCCTX *context,
                        return -1;
                }
        }
-        
+
        srv = SMBC_server(frame, context, True,
                           server, share, &workgroup, &user, &password);
-        
+
        if (!srv) {
                TALLOC_FREE(frame);
                return -1;  /* errno set by SMBC_server */
        }
-        
+
        mode = 0;
-        
+
        if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;
        if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;
        if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
        if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
-        
+
        if (!cli_setatr(srv->cli, path, mode, 0)) {
                errno = SMBC_errno(context, srv->cli);
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        TALLOC_FREE(frame);
         return 0;
 }
@@ -1579,48 +1583,48 @@ SMBC_utimes_ctx(SMBCCTX *context,
         time_t access_time;
         time_t write_time;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
-                
+
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        if (!fname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
         if (tbuf == NULL) {
                 access_time = write_time = time(NULL);
         } else {
                 access_time = tbuf[0].tv_sec;
                 write_time = tbuf[1].tv_sec;
         }
-        
+
         if (DEBUGLVL(4)) {
                 char *p;
                 char atimebuf[32];
                 char mtimebuf[32];
-                
+
                 strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1);
                 atimebuf[sizeof(atimebuf) - 1] = '\0';
                 if ((p = strchr(atimebuf, '\n')) != NULL) {
                         *p = '\0';
                 }
-                
+
                 strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1);
                 mtimebuf[sizeof(mtimebuf) - 1] = '\0';
                 if ((p = strchr(mtimebuf, '\n')) != NULL) {
                         *p = '\0';
                 }
-                
+
                 dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n",
                         fname, atimebuf, mtimebuf);
         }
-        
+
        if (SMBC_parse_path(frame,
                             context,
                             fname,
@@ -1635,7 +1639,7 @@ SMBC_utimes_ctx(SMBCCTX *context,
                TALLOC_FREE(frame);
                return -1;
         }
-        
+
        if (!user || user[0] == (char)0) {
                user = talloc_strdup(frame, smbc_getUser(context));
                if (!user) {
@@ -1644,21 +1648,21 @@ SMBC_utimes_ctx(SMBCCTX *context,
                        return -1;
                }
        }
-        
+
        srv = SMBC_server(frame, context, True,
                           server, share, &workgroup, &user, &password);
-        
+
        if (!srv) {
                TALLOC_FREE(frame);
                return -1;      /* errno set by SMBC_server */
        }
-        
+
         if (!SMBC_setatr(context, srv, path,
                          0, access_time, write_time, 0, 0)) {
                TALLOC_FREE(frame);
                 return -1;      /* errno set by SMBC_setatr */
         }
-        
+
        TALLOC_FREE(frame);
         return 0;
 }
@@ -1681,22 +1685,22 @@ SMBC_unlink_ctx(SMBCCTX *context,
        struct cli_state *targetcli = NULL;
        SMBCSRV *srv = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!context || !context->internal->initialized) {
-                
+
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        if (!fname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        if (SMBC_parse_path(frame,
                             context,
                             fname,
@@ -1711,7 +1715,7 @@ SMBC_unlink_ctx(SMBCCTX *context,
                TALLOC_FREE(frame);
                 return -1;
         }
-        
+
        if (!user || user[0] == (char)0) {
                user = talloc_strdup(frame, smbc_getUser(context));
                if (!user) {
@@ -1720,16 +1724,16 @@ SMBC_unlink_ctx(SMBCCTX *context,
                        return -1;
                }
        }
-        
+
        srv = SMBC_server(frame, context, True,
                           server, share, &workgroup, &user, &password);
-        
+
        if (!srv) {
                TALLOC_FREE(frame);
                return -1;  /* SMBC_server sets errno */
-                
+
        }
-        
+
        /*d_printf(">>>unlink: resolving %s\n", path);*/
        if (!cli_resolve_path(frame, "", srv->cli, path,
                               &targetcli, &targetpath)) {
@@ -1738,13 +1742,13 @@ SMBC_unlink_ctx(SMBCCTX *context,
                return -1;
        }
        /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/
-        
+
        if (!cli_unlink(targetcli, targetpath)) {
-                
+
                errno = SMBC_errno(context, targetcli);
-                
+
                if (errno == EACCES) { /* Check if the file is a directory */
-                        
+
                        int saverr = errno;
                        SMB_OFF_T size = 0;
                        uint16 mode = 0;
@@ -1752,39 +1756,39 @@ SMBC_unlink_ctx(SMBCCTX *context,
                         struct timespec access_time_ts;
                         struct timespec change_time_ts;
                        SMB_INO_T ino = 0;
-                        
+
                        if (!SMBC_getatr(context, srv, path, &mode, &size,
                                         NULL,
                                          &access_time_ts,
                                          &write_time_ts,
                                          &change_time_ts,
                                          &ino)) {
-                                
+
                                /* Hmmm, bad error ... What? */
-                                
+
                                errno = SMBC_errno(context, targetcli);
                                TALLOC_FREE(frame);
                                return -1;
-                                
+
                        }
                        else {
-                                
+
                                if (IS_DOS_DIR(mode))
                                        errno = EISDIR;
                                else
                                        errno = saverr;  /* Restore this */
-                                
+
                        }
                }
-                
+
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        TALLOC_FREE(frame);
        return 0;  /* Success ... */
-        
+
 }
 
 /*
@@ -1793,7 +1797,7 @@ SMBC_unlink_ctx(SMBCCTX *context,
 
 int
 SMBC_rename_ctx(SMBCCTX *ocontext,
-                const char *oname, 
+                const char *oname,
                 SMBCCTX *ncontext,
                 const char *nname)
 {
@@ -1814,24 +1818,24 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
         struct cli_state *targetcli2 = NULL;
        SMBCSRV *srv = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
-        
+
        if (!ocontext || !ncontext ||
            !ocontext->internal->initialized ||
            !ncontext->internal->initialized) {
-                
+
                errno = EINVAL;  /* Best I can think of ... */
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        if (!oname || !nname) {
                errno = EINVAL;
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
-        
+
        if (SMBC_parse_path(frame,
                             ocontext,
                             oname,
@@ -1846,7 +1850,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        if (!user1 || user1[0] == (char)0) {
                user1 = talloc_strdup(frame, smbc_getUser(ocontext));
                if (!user1) {
@@ -1855,7 +1859,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
                        return -1;
                }
        }
-        
+
        if (SMBC_parse_path(frame,
                             ncontext,
                             nname,
@@ -1870,7 +1874,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
                TALLOC_FREE(frame);
                 return -1;
        }
-        
+
        if (!user2 || user2[0] == (char)0) {
                user2 = talloc_strdup(frame, smbc_getUser(ncontext));
                if (!user2) {
@@ -1879,7 +1883,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
                        return -1;
                }
        }
-        
+
        if (strcmp(server1, server2) || strcmp(share1, share2) ||
            strcmp(user1, user2)) {
                /* Can't rename across file systems, or users?? */
@@ -1887,15 +1891,15 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        srv = SMBC_server(frame, ocontext, True,
                           server1, share1, &workgroup, &user1, &password1);
        if (!srv) {
                TALLOC_FREE(frame);
                return -1;
-                
+
        }
-        
+
        /*d_printf(">>>rename: resolving %s\n", path1);*/
        if (!cli_resolve_path(frame, "", srv->cli, path1,
                               &targetcli1, &targetpath1)) {
@@ -1912,7 +1916,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
                return -1;
        }
        /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/
-        
+
        if (strcmp(targetcli1->desthost, targetcli2->desthost) ||
             strcmp(targetcli1->share, targetcli2->share))
        {
@@ -1921,21 +1925,21 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
                TALLOC_FREE(frame);
                return -1;
        }
-        
+
        if (!cli_rename(targetcli1, targetpath1, targetpath2)) {
                int eno = SMBC_errno(ocontext, targetcli1);
-                
+
                if (eno != EEXIST ||
                    !cli_unlink(targetcli1, targetpath2) ||
                    !cli_rename(targetcli1, targetpath1, targetpath2)) {
-                        
+
                        errno = eno;
                        TALLOC_FREE(frame);
                        return -1;
-                        
+
                }
        }
-        
+
        TALLOC_FREE(frame);
        return 0; /* Success */
 }