00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 extern int torture_numops;
00024
00025 static TDB_CONTEXT *tdb;
00026
00027 #define NAME_LENGTH 20
00028
00029 static unsigned total, collisions, failures;
00030
00031 static BOOL test_one(struct cli_state *cli, const char *name)
00032 {
00033 int fnum;
00034 fstring shortname;
00035 fstring name2;
00036 NTSTATUS status;
00037 TDB_DATA data;
00038
00039 total++;
00040
00041 fnum = cli_open(cli, name, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
00042 if (fnum == -1) {
00043 printf("open of %s failed (%s)\n", name, cli_errstr(cli));
00044 return False;
00045 }
00046
00047 if (!cli_close(cli, fnum)) {
00048 printf("close of %s failed (%s)\n", name, cli_errstr(cli));
00049 return False;
00050 }
00051
00052
00053 status = cli_qpathinfo_alt_name(cli, name, shortname);
00054 if (!NT_STATUS_IS_OK(status)) {
00055 printf("query altname of %s failed (%s)\n", name, cli_errstr(cli));
00056 return False;
00057 }
00058
00059 fstr_sprintf(name2, "\\mangle_test\\%s", shortname);
00060 if (!cli_unlink(cli, name2)) {
00061 printf("unlink of %s (%s) failed (%s)\n",
00062 name2, name, cli_errstr(cli));
00063 return False;
00064 }
00065
00066
00067 fnum = cli_open(cli, name2, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
00068 if (fnum == -1) {
00069 printf("open2 of %s failed (%s)\n", name2, cli_errstr(cli));
00070 return False;
00071 }
00072 if (!cli_close(cli, fnum)) {
00073 printf("close of %s failed (%s)\n", name, cli_errstr(cli));
00074 return False;
00075 }
00076
00077
00078 if (!cli_unlink(cli, name)) {
00079 printf("unlink2 of %s (%s) failed (%s)\n",
00080 name, name2, cli_errstr(cli));
00081 failures++;
00082 cli_unlink(cli, name2);
00083 return True;
00084 }
00085
00086
00087 data = tdb_fetch_bystring(tdb, shortname);
00088 if (data.dptr) {
00089
00090 if (!strequal(name, data.dptr)) {
00091
00092 collisions++;
00093 printf("Collision between %s and %s -> %s "
00094 " (coll/tot: %u/%u)\n",
00095 name, data.dptr, shortname, collisions, total);
00096 }
00097 free(data.dptr);
00098 } else {
00099 TDB_DATA namedata;
00100
00101 namedata.dptr = CONST_DISCARD(char *, name);
00102 namedata.dsize = strlen(name)+1;
00103 tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE);
00104 }
00105
00106 return True;
00107 }
00108
00109
00110 static void gen_name(char *name)
00111 {
00112 const char *chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._-$~... ";
00113 unsigned max_idx = strlen(chars);
00114 unsigned len;
00115 int i;
00116 char *p;
00117
00118 fstrcpy(name, "\\mangle_test\\");
00119 p = name + strlen(name);
00120
00121 len = 1 + random() % NAME_LENGTH;
00122
00123 for (i=0;i<len;i++) {
00124 p[i] = chars[random() % max_idx];
00125 }
00126
00127 p[i] = 0;
00128
00129 if (strcmp(p, ".") == 0 || strcmp(p, "..") == 0) {
00130 p[0] = '_';
00131 }
00132
00133
00134 if (random() % 2 == 0) {
00135 p[0] = 'A';
00136 }
00137
00138
00139 if (random() % 10 == 0) {
00140 if (strlen(p) <= 5) {
00141 fstrcpy(p, "ABCDE");
00142 } else {
00143
00144 memcpy(p, "ABCDE", 5);
00145 }
00146 }
00147
00148
00149 if (random() % 2 == 0) {
00150 char *s = strrchr(p, '.');
00151 if (s) {
00152 s[4] = 0;
00153 }
00154 }
00155
00156
00157 if (p[strlen(p)-1] == '.')
00158 p[strlen(p)-1] = '_';
00159 }
00160
00161
00162 BOOL torture_mangle(int dummy)
00163 {
00164 static struct cli_state *cli;
00165 int i;
00166 BOOL ret = True;
00167
00168 printf("starting mangle test\n");
00169
00170 if (!torture_open_connection(&cli, 0)) {
00171 return False;
00172 }
00173
00174
00175 tdb = tdb_open(NULL, 100000, TDB_INTERNAL, 0, 0);
00176 if (!tdb) {
00177 printf("ERROR: Failed to open tdb\n");
00178 return False;
00179 }
00180
00181 cli_unlink(cli, "\\mangle_test\\*");
00182 cli_rmdir(cli, "\\mangle_test");
00183
00184 if (!cli_mkdir(cli, "\\mangle_test")) {
00185 printf("ERROR: Failed to make directory\n");
00186 return False;
00187 }
00188
00189 for (i=0;i<torture_numops;i++) {
00190 fstring name;
00191 ZERO_STRUCT(name);
00192
00193 gen_name(name);
00194
00195 if (!test_one(cli, name)) {
00196 ret = False;
00197 break;
00198 }
00199 if (total && total % 100 == 0) {
00200 printf("collisions %u/%u - %.2f%% (%u failures)\r",
00201 collisions, total, (100.0*collisions) / total, failures);
00202 }
00203 }
00204
00205 cli_unlink(cli, "\\mangle_test\\*");
00206 if (!cli_rmdir(cli, "\\mangle_test")) {
00207 printf("ERROR: Failed to remove directory\n");
00208 return False;
00209 }
00210
00211 printf("\nTotal collisions %u/%u - %.2f%% (%u failures)\n",
00212 collisions, total, (100.0*collisions) / total, failures);
00213
00214 torture_close_connection(cli);
00215
00216 printf("mangle test finished\n");
00217 return (ret && (failures == 0));
00218 }