📄 search.c
字号:
if (io.search_first.out.count != 1) { printf("(%s) search first gave %d entries for dir %d - %s\n", __location__, io.search_first.out.count, i, nt_errstr(status)); ret = false; goto done; } CHECK_STATUS(status, NT_STATUS_OK); if (strncasecmp(file[i].search.name, fname, strlen(fname)) != 0) { printf("(%s) incorrect name '%s' expected '%s'[12].txt\n", __location__, file[i].search.name, fname); ret = false; goto done; } talloc_free(fname); } printf("Search next on %d dirs\n", num_dirs); for (i=0;i<num_dirs;i++) { union smb_search_next io2; io2.search_next.level = RAW_SEARCH_SEARCH; io2.search_next.data_level = RAW_SEARCH_DATA_SEARCH; io2.search_next.in.max_count = 1; io2.search_next.in.search_attrib = 0; io2.search_next.in.id = file[i].search.id; fname = talloc_asprintf(tctx, "f%d-", i); io2.search_next.out.count = 0; status = smb_raw_search_next(cli->tree, tctx, &io2, (void *)&file2[i], single_search_callback); if (io2.search_next.out.count != 1) { printf("(%s) search next gave %d entries for dir %d - %s\n", __location__, io2.search_next.out.count, i, nt_errstr(status)); ret = false; goto done; } CHECK_STATUS(status, NT_STATUS_OK); if (strncasecmp(file2[i].search.name, fname, strlen(fname)) != 0) { printf("(%s) incorrect name '%s' expected '%s'[12].txt\n", __location__, file2[i].search.name, fname); ret = false; goto done; } talloc_free(fname); } printf("Search next (rewind) on %d dirs\n", num_dirs); for (i=0;i<num_dirs;i++) { union smb_search_next io2; io2.search_next.level = RAW_SEARCH_SEARCH; io2.search_next.data_level = RAW_SEARCH_DATA_SEARCH; io2.search_next.in.max_count = 1; io2.search_next.in.search_attrib = 0; io2.search_next.in.id = file[i].search.id; fname = talloc_asprintf(tctx, "f%d-", i); io2.search_next.out.count = 0; status = smb_raw_search_next(cli->tree, tctx, &io2, (void *)&file3[i], single_search_callback); if (io2.search_next.out.count != 1) { printf("(%s) search next gave %d entries for dir %d - %s\n", __location__, io2.search_next.out.count, i, nt_errstr(status)); ret = false; goto done; } CHECK_STATUS(status, NT_STATUS_OK); if (strncasecmp(file3[i].search.name, file2[i].search.name, 3) != 0) { printf("(%s) incorrect name '%s' on rewind at dir %d\n", __location__, file2[i].search.name, i); ret = false; goto done; } if (strcmp(file3[i].search.name, file2[i].search.name) != 0) { printf("(%s) server did not rewind - got '%s' expected '%s'\n", __location__, file3[i].search.name, file2[i].search.name); ret = false; goto done; } talloc_free(fname); }done: smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret;}/* testing of OS/2 style delete*/static bool test_os2_delete(struct torture_context *tctx, struct smbcli_state *cli){ const int num_files = 700; const int delete_count = 4; int total_deleted = 0; int i, fnum; char *fname; bool ret = true; NTSTATUS status; union smb_search_first io; union smb_search_next io2; struct multiple_result result; if (!torture_setup_dir(cli, BASEDIR)) { return false; } printf("Testing OS/2 style delete on %d files\n", num_files); for (i=0;i<num_files;i++) { fname = talloc_asprintf(cli, BASEDIR "\\file%u.txt", i); fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR, DENY_NONE); if (fnum == -1) { printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = false; goto done; } talloc_free(fname); smbcli_close(cli->tree, fnum); } ZERO_STRUCT(result); result.tctx = tctx; io.t2ffirst.level = RAW_SEARCH_TRANS2; io.t2ffirst.data_level = RAW_SEARCH_DATA_EA_SIZE; io.t2ffirst.in.search_attrib = 0; io.t2ffirst.in.max_count = 100; io.t2ffirst.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME; io.t2ffirst.in.storage_type = 0; io.t2ffirst.in.pattern = BASEDIR "\\*"; status = smb_raw_search_first(cli->tree, tctx, &io, &result, multiple_search_callback); CHECK_STATUS(status, NT_STATUS_OK); for (i=0;i<MIN(result.count, delete_count);i++) { fname = talloc_asprintf(cli, BASEDIR "\\%s", result.list[i].ea_size.name.s); status = smbcli_unlink(cli->tree, fname); CHECK_STATUS(status, NT_STATUS_OK); total_deleted++; talloc_free(fname); } io2.t2fnext.level = RAW_SEARCH_TRANS2; io2.t2fnext.data_level = RAW_SEARCH_DATA_EA_SIZE; io2.t2fnext.in.handle = io.t2ffirst.out.handle; io2.t2fnext.in.max_count = 100; io2.t2fnext.in.resume_key = result.list[i-1].ea_size.resume_key; io2.t2fnext.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME; io2.t2fnext.in.last_name = result.list[i-1].ea_size.name.s; do { ZERO_STRUCT(result); result.tctx = tctx; status = smb_raw_search_next(cli->tree, tctx, &io2, &result, multiple_search_callback); if (!NT_STATUS_IS_OK(status)) { break; } for (i=0;i<MIN(result.count, delete_count);i++) { fname = talloc_asprintf(cli, BASEDIR "\\%s", result.list[i].ea_size.name.s); status = smbcli_unlink(cli->tree, fname); CHECK_STATUS(status, NT_STATUS_OK); total_deleted++; talloc_free(fname); } if (i>0) { io2.t2fnext.in.resume_key = result.list[i-1].ea_size.resume_key; io2.t2fnext.in.last_name = result.list[i-1].ea_size.name.s; } } while (NT_STATUS_IS_OK(status) && result.count != 0); CHECK_STATUS(status, NT_STATUS_OK); if (total_deleted != num_files) { printf("error: deleted %d - expected to delete %d\n", total_deleted, num_files); ret = false; }done: smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret;}static int ealist_cmp(union smb_search_data *r1, union smb_search_data *r2){ return strcmp(r1->ea_list.name.s, r2->ea_list.name.s);}/* testing of the rather strange ea_list level*/static bool test_ea_list(struct torture_context *tctx, struct smbcli_state *cli){ int fnum; bool ret = true; NTSTATUS status; union smb_search_first io; union smb_search_next nxt; struct multiple_result result; union smb_setfileinfo setfile; if (!torture_setup_dir(cli, BASEDIR)) { return false; } printf("Testing RAW_SEARCH_EA_LIST level\n"); fnum = smbcli_open(cli->tree, BASEDIR "\\file1.txt", O_CREAT|O_RDWR, DENY_NONE); smbcli_close(cli->tree, fnum); fnum = smbcli_open(cli->tree, BASEDIR "\\file2.txt", O_CREAT|O_RDWR, DENY_NONE); smbcli_close(cli->tree, fnum); fnum = smbcli_open(cli->tree, BASEDIR "\\file3.txt", O_CREAT|O_RDWR, DENY_NONE); smbcli_close(cli->tree, fnum); setfile.generic.level = RAW_SFILEINFO_EA_SET; setfile.generic.in.file.path = BASEDIR "\\file2.txt"; setfile.ea_set.in.num_eas = 2; setfile.ea_set.in.eas = talloc_array(tctx, struct ea_struct, 2); setfile.ea_set.in.eas[0].flags = 0; setfile.ea_set.in.eas[0].name.s = "EA ONE"; setfile.ea_set.in.eas[0].value = data_blob_string_const("VALUE 1"); setfile.ea_set.in.eas[1].flags = 0; setfile.ea_set.in.eas[1].name.s = "SECOND EA"; setfile.ea_set.in.eas[1].value = data_blob_string_const("Value Two"); status = smb_raw_setpathinfo(cli->tree, &setfile); CHECK_STATUS(status, NT_STATUS_OK); setfile.generic.in.file.path = BASEDIR "\\file3.txt"; status = smb_raw_setpathinfo(cli->tree, &setfile); CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(result); result.tctx = tctx; io.t2ffirst.level = RAW_SEARCH_TRANS2; io.t2ffirst.data_level = RAW_SEARCH_DATA_EA_LIST; io.t2ffirst.in.search_attrib = 0; io.t2ffirst.in.max_count = 2; io.t2ffirst.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME; io.t2ffirst.in.storage_type = 0; io.t2ffirst.in.pattern = BASEDIR "\\*"; io.t2ffirst.in.num_names = 2; io.t2ffirst.in.ea_names = talloc_array(tctx, struct ea_name, 2); io.t2ffirst.in.ea_names[0].name.s = "SECOND EA"; io.t2ffirst.in.ea_names[1].name.s = "THIRD EA"; status = smb_raw_search_first(cli->tree, tctx, &io, &result, multiple_search_callback); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(result.count, 2); nxt.t2fnext.level = RAW_SEARCH_TRANS2; nxt.t2fnext.data_level = RAW_SEARCH_DATA_EA_LIST; nxt.t2fnext.in.handle = io.t2ffirst.out.handle; nxt.t2fnext.in.max_count = 2; nxt.t2fnext.in.resume_key = result.list[1].ea_list.resume_key; nxt.t2fnext.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME | FLAG_TRANS2_FIND_CONTINUE; nxt.t2fnext.in.last_name = result.list[1].ea_list.name.s; nxt.t2fnext.in.num_names = 2; nxt.t2fnext.in.ea_names = talloc_array(tctx, struct ea_name, 2); nxt.t2fnext.in.ea_names[0].name.s = "SECOND EA"; nxt.t2fnext.in.ea_names[1].name.s = "THIRD EA"; status = smb_raw_search_next(cli->tree, tctx, &nxt, &result, multiple_search_callback); CHECK_STATUS(status, NT_STATUS_OK); /* we have to sort the result as different servers can return directories in different orders */ qsort(result.list, result.count, sizeof(result.list[0]), (comparison_fn_t)ealist_cmp); CHECK_VALUE(result.count, 3); CHECK_VALUE(result.list[0].ea_list.eas.num_eas, 2); CHECK_STRING(result.list[0].ea_list.name.s, "file1.txt"); CHECK_STRING(result.list[0].ea_list.eas.eas[0].name.s, "SECOND EA"); CHECK_VALUE(result.list[0].ea_list.eas.eas[0].value.length, 0); CHECK_STRING(result.list[0].ea_list.eas.eas[1].name.s, "THIRD EA"); CHECK_VALUE(result.list[0].ea_list.eas.eas[1].value.length, 0); CHECK_STRING(result.list[1].ea_list.name.s, "file2.txt"); CHECK_STRING(result.list[1].ea_list.eas.eas[0].name.s, "SECOND EA"); CHECK_VALUE(result.list[1].ea_list.eas.eas[0].value.length, 9); CHECK_STRING((const char *)result.list[1].ea_list.eas.eas[0].value.data, "Value Two"); CHECK_STRING(result.list[1].ea_list.eas.eas[1].name.s, "THIRD EA"); CHECK_VALUE(result.list[1].ea_list.eas.eas[1].value.length, 0); CHECK_STRING(result.list[2].ea_list.name.s, "file3.txt"); CHECK_STRING(result.list[2].ea_list.eas.eas[0].name.s, "SECOND EA"); CHECK_VALUE(result.list[2].ea_list.eas.eas[0].value.length, 9); CHECK_STRING((const char *)result.list[2].ea_list.eas.eas[0].value.data, "Value Two"); CHECK_STRING(result.list[2].ea_list.eas.eas[1].name.s, "THIRD EA"); CHECK_VALUE(result.list[2].ea_list.eas.eas[1].value.length, 0); smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret;}/* basic testing of all RAW_SEARCH_* calls using a single file*/struct torture_suite *torture_raw_search(TALLOC_CTX *mem_ctx){ struct torture_suite *suite = torture_suite_create(mem_ctx, "SEARCH"); torture_suite_add_1smb_test(suite, "one file search", test_one_file); torture_suite_add_1smb_test(suite, "many files", test_many_files); torture_suite_add_1smb_test(suite, "sorted", test_sorted); torture_suite_add_1smb_test(suite, "modify search", test_modify_search); torture_suite_add_1smb_test(suite, "many dirs", test_many_dirs); torture_suite_add_1smb_test(suite, "os2 delete", test_os2_delete); torture_suite_add_1smb_test(suite, "ea list", test_ea_list); return suite;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -