static NTSTATUS gp_do_list (const char *rel_path, struct gp_list_state *state) { uint16_t attributes; int rv; char *mask; const char *old_rel_path; attributes = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; /* Update the relative paths, while buffering the parent */ old_rel_path = state->cur_rel_path; state->cur_rel_path = rel_path; state->depth++; /* Get the current mask */ mask = talloc_asprintf(state, "%s%s\\*", state->share_path, rel_path); NT_STATUS_HAVE_NO_MEMORY(mask); rv = smbcli_list(state->tree, mask, attributes, gp_list_helper, state); talloc_free(mask); /* Go back to the state of the parent */ state->cur_rel_path = old_rel_path; state->depth--; if (rv == -1) return NT_STATUS_UNSUCCESSFUL; return NT_STATUS_OK; }
bool torture_samba3_caseinsensitive(struct torture_context *torture) { struct smbcli_state *cli; TALLOC_CTX *mem_ctx; NTSTATUS status; const char *dirname = "insensitive"; const char *ucase_dirname = "InSeNsItIvE"; const char *fname = "foo"; char *fpath; int fnum; int counter = 0; bool ret = true; if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) { d_printf("talloc_init failed\n"); return false; } if (!torture_open_connection(&cli, torture, 0)) { goto done; } smbcli_deltree(cli->tree, dirname); status = smbcli_mkdir(cli->tree, dirname); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status)); goto done; } if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) { goto done; } fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE); if (fnum == -1) { d_printf("Could not create file %s: %s\n", fpath, smbcli_errstr(cli->tree)); goto done; } smbcli_close(cli->tree, fnum); smbcli_list(cli->tree, talloc_asprintf( mem_ctx, "%s\\*", ucase_dirname), FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN |FILE_ATTRIBUTE_SYSTEM, count_fn, (void *)&counter); if (counter == 3) { ret = true; } else { d_fprintf(stderr, "expected 3 entries, got %d\n", counter); ret = false; } done: talloc_free(mem_ctx); return ret; }
/* recursively descend a tree deleting all files returns the number of files deleted, or -1 on error */ 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; /* it might be a file */ status = smbcli_unlink(tree, dname); if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) { 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_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); smbcli_unlink(dstate.tree, mask); smbcli_list(dstate.tree, mask, FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, &dstate); free(mask); 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; } dstate.total_deleted++; if (dstate.failed) { return -1; } return dstate.total_deleted; }
/* test directory listing speed */ bool torture_dirtest1(struct torture_context *tctx, struct smbcli_state *cli) { int i; int fnum; bool correct = true; extern int torture_numops; struct timeval tv; torture_comment(tctx, "Creating %d random filenames\n", torture_numops); srandom(0); tv = timeval_current(); for (i=0;i<torture_numops;i++) { char *fname; asprintf(&fname, "\\%x", (int)random()); fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { fprintf(stderr,"(%s) Failed to open %s\n", __location__, fname); return false; } smbcli_close(cli->tree, fnum); free(fname); } torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL)); torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL)); torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL)); torture_comment(tctx, "dirtest core %g seconds\n", timeval_elapsed(&tv)); srandom(0); for (i=0;i<torture_numops;i++) { char *fname; asprintf(&fname, "\\%x", (int)random()); smbcli_unlink(cli->tree, fname); free(fname); } return correct; }
static bool is_visible(struct smbcli_tree *tree, const char *fname) { struct list_state state; state.visible = false; state.fname = fname; if (smbcli_list(tree, "*.*", 0, set_visible, &state) < 0) { return false; } return state.visible; }
bool torture_samba3_caseinsensitive(struct torture_context *torture, struct smbcli_state *cli) { TALLOC_CTX *mem_ctx; const char *dirname = "insensitive"; const char *ucase_dirname = "InSeNsItIvE"; const char *fname = "foo"; char *fpath; int fnum; int counter = 0; bool ret = false; if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) { torture_result(torture, TORTURE_FAIL, "talloc_init failed\n"); return false; } torture_assert(torture, torture_setup_dir(cli, dirname), "creating test directory"); if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) { goto done; } fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE); if (fnum == -1) { torture_result(torture, TORTURE_FAIL, "Could not create file %s: %s", fpath, smbcli_errstr(cli->tree)); goto done; } smbcli_close(cli->tree, fnum); smbcli_list(cli->tree, talloc_asprintf( mem_ctx, "%s\\*", ucase_dirname), FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN |FILE_ATTRIBUTE_SYSTEM, count_fn, (void *)&counter); if (counter == 3) { ret = true; } else { torture_result(torture, TORTURE_FAIL, "expected 3 entries, got %d", counter); ret = false; } done: talloc_free(mem_ctx); return ret; }
static bool gpo_sync_files(struct sync_context *ctx) { DEBUG(3,("calling cli_list with mask: %s\n", ctx->mask)); if (smbcli_list(ctx->cli->tree, ctx->mask, ctx->attribute, gpo_sync_func, ctx) == -1) { DEBUG(1,("listing [%s] failed with error: %s\n", ctx->mask, smbcli_errstr(ctx->cli->tree))); return false; } return true; }
/* callback function for torture_deltree() */ static void delete_fn(struct clilist_file_info *finfo, const char *name, void *state) { struct delete_state *dstate = (struct delete_state *)state; char *s, *n; if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) { return; } n = strdup(name); n[strlen(n)-1] = 0; asprintf(&s, "%s%s", n, finfo->name); if (finfo->attrib & FILE_ATTRIBUTE_READONLY) { if (NT_STATUS_IS_ERR(smbcli_setatr(dstate->tree, s, 0, 0))) { DEBUG(2,("Failed to remove READONLY on %s - %s\n", s, smbcli_errstr(dstate->tree))); } } if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) { char *s2; asprintf(&s2, "%s\\*", s); smbcli_unlink(dstate->tree, s2); smbcli_list(dstate->tree, s2, FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, state); free(s2); 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->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->total_deleted++; } free(s); free(n); }
static int ejs_list(MprVarHandle eid, int argc, MprVar **argv) { struct smbcli_tree *tree; char *mask; uint16_t attribute; MprVar result; if (argc != 3) { ejsSetErrorMsg(eid, "list(): invalid number of args"); return -1; } if (!IS_TREE_HANDLE(argv[0])) { ejsSetErrorMsg(eid, "first arg is not a tree handle"); return -1; } tree = argv[0]->ptr; if (!mprVarIsString(argv[1]->type)) { ejsSetErrorMsg(eid, "arg 2 must be a string"); return -1; } mask = argv[1]->string; if (!mprVarIsNumber(argv[2]->type)) { ejsSetErrorMsg(eid, "arg 3 must be a number"); return -1; } attribute = mprVarToInteger(argv[2]); result = mprObject("list"); smbcli_list(tree, mask, attribute, ejs_list_helper, &result); mpr_Return(eid, result); return 0; }
bool torture_dirtest2(struct torture_context *tctx, struct smbcli_state *cli) { int i; int fnum, num_seen; bool correct = true; extern int torture_entries; if (!torture_setup_dir(cli, "\\LISTDIR")) { return false; } torture_comment(tctx, "Creating %d files\n", torture_entries); /* Create torture_entries files and torture_entries directories. */ for (i=0;i<torture_entries;i++) { char *fname; asprintf(&fname, "\\LISTDIR\\f%d", i); fnum = smbcli_nt_create_full(cli->tree, fname, 0, SEC_RIGHTS_FILE_ALL, FILE_ATTRIBUTE_ARCHIVE, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0); if (fnum == -1) { fprintf(stderr,"(%s) Failed to open %s, error=%s\n", __location__, fname, smbcli_errstr(cli->tree)); return false; } free(fname); smbcli_close(cli->tree, fnum); } for (i=0;i<torture_entries;i++) { char *fname; asprintf(&fname, "\\LISTDIR\\d%d", i); if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) { fprintf(stderr,"(%s) Failed to open %s, error=%s\n", __location__, fname, smbcli_errstr(cli->tree)); return false; } free(fname); } /* Now ensure that doing an old list sees both files and directories. */ num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL); torture_comment(tctx, "num_seen = %d\n", num_seen ); /* We should see (torture_entries) each of files & directories + . and .. */ if (num_seen != (2*torture_entries)+2) { correct = false; fprintf(stderr,"(%s) entry count mismatch, should be %d, was %d\n", __location__, (2*torture_entries)+2, num_seen); } /* Ensure if we have the "must have" bits we only see the * relevant entries. */ num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL); torture_comment(tctx, "num_seen = %d\n", num_seen ); if (num_seen != torture_entries+2) { correct = false; fprintf(stderr,"(%s) entry count mismatch, should be %d, was %d\n", __location__, torture_entries+2, num_seen); } num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL); torture_comment(tctx, "num_seen = %d\n", num_seen ); if (num_seen != torture_entries) { correct = false; fprintf(stderr,"(%s) entry count mismatch, should be %d, was %d\n", __location__, torture_entries, num_seen); } /* Delete everything. */ if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) { fprintf(stderr,"(%s) Failed to deltree %s, error=%s\n", "\\LISTDIR", __location__, smbcli_errstr(cli->tree)); return false; } #if 0 torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL)); torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL)); torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL)); #endif return correct; }