PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/release/src/router/samba/source/utils/masktest.c

https://gitlab.com/envieidoc/tomato
C | 435 lines | 318 code | 82 blank | 35 comment | 59 complexity | c312924663a4a6a9e752fc81b539c4a9 MD5 | raw file
  1. /*
  2. Unix SMB/Netbios implementation.
  3. Version 2.0
  4. mask_match tester
  5. Copyright (C) Andrew Tridgell 1999
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #define NO_SYSLOG
  19. #include "includes.h"
  20. extern int DEBUGLEVEL;
  21. static fstring password;
  22. static fstring username;
  23. static fstring workgroup;
  24. static int got_pass;
  25. static BOOL showall = False;
  26. static char *maskchars = "<>\"?*abc.";
  27. static char *filechars = "abcdefghijklm.";
  28. char *standard_masks[] = {"*", "*.", "*.*",
  29. ".*", "d2.??", "d2\">>",
  30. NULL};
  31. char *standard_files[] = {"abc", "abc.", ".abc",
  32. "abc.def", "abc.de.f",
  33. "d2.x",
  34. NULL};
  35. #include <regex.h>
  36. static char *reg_test(char *pattern, char *file)
  37. {
  38. static fstring ret;
  39. pstring rpattern;
  40. regex_t preg;
  41. pattern = 1+strrchr(pattern,'\\');
  42. file = 1+strrchr(file,'\\');
  43. fstrcpy(ret,"---");
  44. if (strcmp(file,"..") == 0) file = ".";
  45. if (strcmp(pattern,".") == 0) return ret;
  46. if (strcmp(pattern,"") == 0) {
  47. ret[2] = '+';
  48. return ret;
  49. }
  50. pstrcpy(rpattern,"^");
  51. pstrcat(rpattern, pattern);
  52. all_string_sub(rpattern,".", "[.]", 0);
  53. all_string_sub(rpattern,"?", ".{1}", 0);
  54. all_string_sub(rpattern,"*", ".*", 0);
  55. all_string_sub(rpattern+strlen(rpattern)-1,">", "([^.]?|[.]?$)", 0);
  56. all_string_sub(rpattern,">", "[^.]?", 0);
  57. all_string_sub(rpattern,"<[.]", ".*[.]", 0);
  58. all_string_sub(rpattern,"<\"", "(.*[.]|.*$)", 0);
  59. all_string_sub(rpattern,"<", "([^.]*|[^.]*[.]|[.][^.]*|[.].*[.])", 0);
  60. if (strlen(pattern)>1) {
  61. all_string_sub(rpattern+strlen(rpattern)-1,"\"", "[.]?", 0);
  62. }
  63. all_string_sub(rpattern,"\"", "([.]|$)", 0);
  64. pstrcat(rpattern,"$");
  65. /* printf("pattern=[%s] rpattern=[%s]\n", pattern, rpattern); */
  66. regcomp(&preg, rpattern, REG_ICASE|REG_NOSUB|REG_EXTENDED);
  67. if (regexec(&preg, ".", 0, NULL, 0) == 0) {
  68. ret[0] = '+';
  69. ret[1] = '+';
  70. }
  71. if (regexec(&preg, file, 0, NULL, 0) == 0) {
  72. ret[2] = '+';
  73. }
  74. regfree(&preg);
  75. return ret;
  76. }
  77. /*****************************************************
  78. return a connection to a server
  79. *******************************************************/
  80. struct cli_state *connect_one(char *share)
  81. {
  82. struct cli_state *c;
  83. struct nmb_name called, calling;
  84. char *server_n;
  85. char *server;
  86. struct in_addr ip;
  87. extern struct in_addr ipzero;
  88. server = share+2;
  89. share = strchr(server,'\\');
  90. if (!share) return NULL;
  91. *share = 0;
  92. share++;
  93. server_n = server;
  94. ip = ipzero;
  95. make_nmb_name(&calling, "masktest", 0x0, "");
  96. make_nmb_name(&called , server, 0x20, "");
  97. again:
  98. ip = ipzero;
  99. /* have to open a new connection */
  100. if (!(c=cli_initialise(NULL)) || (cli_set_port(c, 139) == 0) ||
  101. !cli_connect(c, server_n, &ip)) {
  102. DEBUG(0,("Connection to %s failed\n", server_n));
  103. return NULL;
  104. }
  105. if (!cli_session_request(c, &calling, &called)) {
  106. DEBUG(0,("session request to %s failed\n", called.name));
  107. cli_shutdown(c);
  108. if (strcmp(called.name, "*SMBSERVER")) {
  109. make_nmb_name(&called , "*SMBSERVER", 0x20, "");
  110. goto again;
  111. }
  112. return NULL;
  113. }
  114. DEBUG(4,(" session request ok\n"));
  115. if (!cli_negprot(c)) {
  116. DEBUG(0,("protocol negotiation failed\n"));
  117. cli_shutdown(c);
  118. return NULL;
  119. }
  120. if (!got_pass) {
  121. char *pass = getpass("Password: ");
  122. if (pass) {
  123. pstrcpy(password, pass);
  124. }
  125. }
  126. if (!cli_session_setup(c, username,
  127. password, strlen(password),
  128. password, strlen(password),
  129. workgroup)) {
  130. DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
  131. return NULL;
  132. }
  133. /*
  134. * These next two lines are needed to emulate
  135. * old client behaviour for people who have
  136. * scripts based on client output.
  137. * QUESTION ? Do we want to have a 'client compatibility
  138. * mode to turn these on/off ? JRA.
  139. */
  140. if (*c->server_domain || *c->server_os || *c->server_type)
  141. DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
  142. c->server_domain,c->server_os,c->server_type));
  143. DEBUG(4,(" session setup ok\n"));
  144. if (!cli_send_tconX(c, share, "?????",
  145. password, strlen(password)+1)) {
  146. DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
  147. cli_shutdown(c);
  148. return NULL;
  149. }
  150. DEBUG(4,(" tconx ok\n"));
  151. return c;
  152. }
  153. static char *resultp;
  154. void listfn(file_info *f, const char *s)
  155. {
  156. if (strcmp(f->name,".") == 0) {
  157. resultp[0] = '+';
  158. } else if (strcmp(f->name,"..") == 0) {
  159. resultp[1] = '+';
  160. } else {
  161. resultp[2] = '+';
  162. }
  163. }
  164. static void testpair(struct cli_state *cli1, struct cli_state *cli2,
  165. char *mask, char *file)
  166. {
  167. int fnum;
  168. fstring res1, res2;
  169. char *res3;
  170. static int count;
  171. count++;
  172. fstrcpy(res1, "---");
  173. fstrcpy(res2, "---");
  174. fnum = cli_open(cli1, file, O_CREAT|O_TRUNC|O_RDWR, 0);
  175. if (fnum == -1) {
  176. DEBUG(0,("Can't create %s on cli1\n", file));
  177. return;
  178. }
  179. cli_close(cli1, fnum);
  180. fnum = cli_open(cli2, file, O_CREAT|O_TRUNC|O_RDWR, 0);
  181. if (fnum == -1) {
  182. DEBUG(0,("Can't create %s on cli2\n", file));
  183. return;
  184. }
  185. cli_close(cli2, fnum);
  186. resultp = res1;
  187. cli_list(cli1, mask, aHIDDEN | aDIR, listfn);
  188. res3 = reg_test(mask, file);
  189. resultp = res2;
  190. cli_list(cli2, mask, aHIDDEN | aDIR, listfn);
  191. if (showall || strcmp(res1, res2)) {
  192. DEBUG(0,("%s %s %s %d mask=[%s] file=[%s]\n",
  193. res1, res2, res3, count, mask, file));
  194. }
  195. cli_unlink(cli1, file);
  196. cli_unlink(cli2, file);
  197. }
  198. static void test_mask(int argc, char *argv[],
  199. struct cli_state *cli1, struct cli_state *cli2)
  200. {
  201. pstring mask, file;
  202. int l1, l2, i, j, l;
  203. int mc_len = strlen(maskchars);
  204. int fc_len = strlen(filechars);
  205. cli_mkdir(cli1, "masktest");
  206. cli_mkdir(cli2, "masktest");
  207. cli_unlink(cli1, "\\masktest\\*");
  208. cli_unlink(cli2, "\\masktest\\*");
  209. if (argc >= 2) {
  210. while (argc >= 2) {
  211. pstrcpy(mask,"\\masktest\\");
  212. pstrcpy(file,"\\masktest\\");
  213. pstrcat(mask, argv[0]);
  214. pstrcat(file, argv[1]);
  215. testpair(cli1, cli2, mask, file);
  216. argv += 2;
  217. argc -= 2;
  218. }
  219. goto finished;
  220. }
  221. for (i=0; standard_masks[i]; i++) {
  222. for (j=0; standard_files[j]; j++) {
  223. pstrcpy(mask,"\\masktest\\");
  224. pstrcpy(file,"\\masktest\\");
  225. pstrcat(mask, standard_masks[i]);
  226. pstrcat(file, standard_files[j]);
  227. testpair(cli1, cli2, mask, file);
  228. }
  229. }
  230. while (1) {
  231. l1 = 1 + random() % 20;
  232. l2 = 1 + random() % 20;
  233. pstrcpy(mask,"\\masktest\\");
  234. pstrcpy(file,"\\masktest\\");
  235. l = strlen(mask);
  236. for (i=0;i<l1;i++) {
  237. mask[i+l] = maskchars[random() % mc_len];
  238. }
  239. mask[l+l1] = 0;
  240. for (i=0;i<l2;i++) {
  241. file[i+l] = filechars[random() % fc_len];
  242. }
  243. file[l+l2] = 0;
  244. if (strcmp(file+l,".") == 0 ||
  245. strcmp(file+l,"..") == 0 ||
  246. strcmp(mask+l,"..") == 0) continue;
  247. testpair(cli1, cli2, mask, file);
  248. }
  249. finished:
  250. cli_rmdir(cli1, "\\masktest");
  251. cli_rmdir(cli2, "\\masktest");
  252. }
  253. static void usage(void)
  254. {
  255. printf(
  256. "Usage:\n\
  257. masktest //server1/share1 //server2/share2 [options..]\n\
  258. options:\n\
  259. -U user%%pass\n\
  260. -s seed\n\
  261. -f filechars (default %s)\n\
  262. -m maskchars (default %s)\n\
  263. -a show all tests\n\
  264. \n\
  265. This program tests wildcard matching between two servers. It generates\n\
  266. random pairs of filenames/masks and tests that they match in the same\n\
  267. way on two servers\n\
  268. ",
  269. filechars, maskchars);
  270. }
  271. /****************************************************************************
  272. main program
  273. ****************************************************************************/
  274. int main(int argc,char *argv[])
  275. {
  276. char *share1, *share2;
  277. struct cli_state *cli1, *cli2;
  278. extern char *optarg;
  279. extern int optind;
  280. extern FILE *dbf;
  281. int opt;
  282. char *p;
  283. int seed;
  284. setlinebuf(stdout);
  285. dbf = stderr;
  286. if (argv[1][0] == '-' || argc < 3) {
  287. usage();
  288. exit(1);
  289. }
  290. share1 = argv[1];
  291. share2 = argv[2];
  292. all_string_sub(share1,"/","\\",0);
  293. all_string_sub(share2,"/","\\",0);
  294. setup_logging(argv[0],True);
  295. argc -= 2;
  296. argv += 2;
  297. TimeInit();
  298. charset_initialise();
  299. if (getenv("USER")) {
  300. pstrcpy(username,getenv("USER"));
  301. }
  302. seed = time(NULL);
  303. while ((opt = getopt(argc, argv, "U:s:hm:f:a")) != EOF) {
  304. switch (opt) {
  305. case 'U':
  306. pstrcpy(username,optarg);
  307. p = strchr(username,'%');
  308. if (p) {
  309. *p = 0;
  310. pstrcpy(password, p+1);
  311. got_pass = 1;
  312. }
  313. break;
  314. case 's':
  315. seed = atoi(optarg);
  316. break;
  317. case 'h':
  318. usage();
  319. exit(1);
  320. case 'm':
  321. maskchars = optarg;
  322. break;
  323. case 'f':
  324. filechars = optarg;
  325. break;
  326. case 'a':
  327. showall = 1;
  328. break;
  329. default:
  330. printf("Unknown option %c (%d)\n", (char)opt, opt);
  331. exit(1);
  332. }
  333. }
  334. argc -= optind;
  335. argv += optind;
  336. DEBUG(0,("seed=%d\n", seed));
  337. srandom(seed);
  338. cli1 = connect_one(share1);
  339. if (!cli1) {
  340. DEBUG(0,("Failed to connect to %s\n", share1));
  341. exit(1);
  342. }
  343. cli2 = connect_one(share2);
  344. if (!cli2) {
  345. DEBUG(0,("Failed to connect to %s\n", share2));
  346. exit(1);
  347. }
  348. test_mask(argc, argv, cli1, cli2);
  349. return(0);
  350. }