torture/mangle_test.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    SMB torture tester - mangling test
00004    Copyright (C) Andrew Tridgell 2002
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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         /* get the short name */
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         /* recreate by short name */
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         /* and unlink by long name */
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         /* see if the short name is already in the tdb */
00087         data = tdb_fetch_bystring(tdb, shortname);
00088         if (data.dptr) {
00089                 /* maybe its a duplicate long name? */
00090                 if (!strequal(name, data.dptr)) {
00091                         /* we have a collision */
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                 /* store it for later */
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         /* have a high probability of a common lead char */
00134         if (random() % 2 == 0) {
00135                 p[0] = 'A';
00136         }
00137 
00138         /* and a medium probability of a common lead string */
00139         if (random() % 10 == 0) {
00140                 if (strlen(p) <= 5) {
00141                         fstrcpy(p, "ABCDE");
00142                 } else {
00143                         /* try not to kill off the null termination */
00144                         memcpy(p, "ABCDE", 5);
00145                 }
00146         }
00147 
00148         /* and a high probability of a good extension length */
00149         if (random() % 2 == 0) {
00150                 char *s = strrchr(p, '.');
00151                 if (s) {
00152                         s[4] = 0;
00153                 }
00154         }
00155 
00156         /* ..... and a 100% proability of a file not ending in "." */
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         /* we will use an internal tdb to store the names we have used */
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 }

Sambaに対してSat Aug 29 21:23:27 2009に生成されました。  doxygen 1.4.7