ntvfs: Remove unused and untested SMB1 -> SMB2 proxy module
[bbaumbach/samba-autobuild/.git] / source4 / libcli / clideltree.c
index d191bd277a55528e8d0251a0beca12ed575a467e..e8007f4495a2f8843fe796d281a9f8436379dc69 100644 (file)
@@ -25,7 +25,7 @@
 struct delete_state {
        struct smbcli_tree *tree;
        int total_deleted;
-       BOOL failed;
+       bool failed;
 };
 
 /* 
@@ -41,7 +41,10 @@ static void delete_fn(struct clilist_file_info *finfo, const char *name, void *s
 
        n = strdup(name);
        n[strlen(n)-1] = 0;
-       asprintf(&s, "%s%s", n, finfo->name);
+       if (asprintf(&s, "%s%s", n, finfo->name) < 0) {
+               free(n);
+               return;
+       }
 
        if (finfo->attrib & FILE_ATTRIBUTE_READONLY) {
                if (NT_STATUS_IS_ERR(smbcli_setatr(dstate->tree, s, 0, 0))) {
@@ -52,7 +55,11 @@ static void delete_fn(struct clilist_file_info *finfo, const char *name, void *s
 
        if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) {
                char *s2;
-               asprintf(&s2, "%s\\*", s);
+               if (asprintf(&s2, "%s\\*", s) < 0) {
+                       free(s);
+                       free(n);
+                       return;
+               }
                smbcli_unlink(dstate->tree, s2);
                smbcli_list(dstate->tree, s2, 
                         FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, 
@@ -61,14 +68,14 @@ static void delete_fn(struct clilist_file_info *finfo, const char *name, void *s
                if (NT_STATUS_IS_ERR(smbcli_rmdir(dstate->tree, s))) {
                        DEBUG(2,("Failed to delete %s - %s\n", 
                                 s, smbcli_errstr(dstate->tree)));
-                       dstate->failed = True;
+                       dstate->failed = true;
                }
                dstate->total_deleted++;
        } else {
                if (NT_STATUS_IS_ERR(smbcli_unlink(dstate->tree, s))) {
                        DEBUG(2,("Failed to delete %s - %s\n", 
                                 s, smbcli_errstr(dstate->tree)));
-                       dstate->failed = True;
+                       dstate->failed = true;
                }
                dstate->total_deleted++;
        }
@@ -84,28 +91,47 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname)
 {
        char *mask;
        struct delete_state dstate;
+       NTSTATUS status;
 
        dstate.tree = tree;
        dstate.total_deleted = 0;
-       dstate.failed = False;
+       dstate.failed = false;
 
        /* it might be a file */
-       if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) {
+       status = smbcli_unlink(tree, dname);
+       if (NT_STATUS_IS_OK(status)) {
                return 1;
        }
        if (NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
            NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
-           NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE)) {
+           NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE) ||
+           NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_DOS(ERRDOS, ERRbadfile))) {
                return 0;
        }
+       if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+               /* it could be read-only */
+               status = smbcli_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL, 0);
+               if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) {
+                       return 1;
+               }
+       }
 
-       asprintf(&mask, "%s\\*", dname);
+       if (asprintf(&mask, "%s\\*", dname) < 0) {
+               return -1;
+       }
        smbcli_unlink(dstate.tree, mask);
        smbcli_list(dstate.tree, mask, 
                 FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, 
                 delete_fn, &dstate);
        free(mask);
-       if (NT_STATUS_IS_ERR(smbcli_rmdir(dstate.tree, dname))) {
+
+       status = smbcli_rmdir(dstate.tree, dname);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+               /* it could be read-only */
+               status = smbcli_setatr(dstate.tree, dname, FILE_ATTRIBUTE_NORMAL, 0);
+               status = smbcli_rmdir(dstate.tree, dname);
+       }
+       if (NT_STATUS_IS_ERR(status)) {
                DEBUG(2,("Failed to delete %s - %s\n", 
                         dname, smbcli_errstr(dstate.tree)));
                return -1;