Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / samba / source / utils / masktest.c
blobb4d919fe7c0e93ca6390507143369fa634878349
1 /*
2 Unix SMB/Netbios implementation.
3 Version 2.0
4 mask_match tester
5 Copyright (C) Andrew Tridgell 1999
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #define NO_SYSLOG
24 #include "includes.h"
26 extern int DEBUGLEVEL;
27 static fstring password;
28 static fstring username;
29 static fstring workgroup;
30 static int got_pass;
32 static BOOL showall = False;
34 static char *maskchars = "<>\"?*abc.";
35 static char *filechars = "abcdefghijklm.";
37 char *standard_masks[] = {"*", "*.", "*.*",
38 ".*", "d2.??", "d2\">>",
39 NULL};
40 char *standard_files[] = {"abc", "abc.", ".abc",
41 "abc.def", "abc.de.f",
42 "d2.x",
43 NULL};
46 #include <regex.h>
48 static char *reg_test(char *pattern, char *file)
50 static fstring ret;
51 pstring rpattern;
52 regex_t preg;
54 pattern = 1+strrchr(pattern,'\\');
55 file = 1+strrchr(file,'\\');
57 fstrcpy(ret,"---");
59 if (strcmp(file,"..") == 0) file = ".";
60 if (strcmp(pattern,".") == 0) return ret;
62 if (strcmp(pattern,"") == 0) {
63 ret[2] = '+';
64 return ret;
67 pstrcpy(rpattern,"^");
68 pstrcat(rpattern, pattern);
70 all_string_sub(rpattern,".", "[.]", 0);
71 all_string_sub(rpattern,"?", ".{1}", 0);
72 all_string_sub(rpattern,"*", ".*", 0);
73 all_string_sub(rpattern+strlen(rpattern)-1,">", "([^.]?|[.]?$)", 0);
74 all_string_sub(rpattern,">", "[^.]?", 0);
76 all_string_sub(rpattern,"<[.]", ".*[.]", 0);
77 all_string_sub(rpattern,"<\"", "(.*[.]|.*$)", 0);
78 all_string_sub(rpattern,"<", "([^.]*|[^.]*[.]|[.][^.]*|[.].*[.])", 0);
79 if (strlen(pattern)>1) {
80 all_string_sub(rpattern+strlen(rpattern)-1,"\"", "[.]?", 0);
82 all_string_sub(rpattern,"\"", "([.]|$)", 0);
83 pstrcat(rpattern,"$");
85 /* printf("pattern=[%s] rpattern=[%s]\n", pattern, rpattern); */
87 regcomp(&preg, rpattern, REG_ICASE|REG_NOSUB|REG_EXTENDED);
88 if (regexec(&preg, ".", 0, NULL, 0) == 0) {
89 ret[0] = '+';
90 ret[1] = '+';
92 if (regexec(&preg, file, 0, NULL, 0) == 0) {
93 ret[2] = '+';
95 regfree(&preg);
97 return ret;
101 /*****************************************************
102 return a connection to a server
103 *******************************************************/
104 struct cli_state *connect_one(char *share)
106 struct cli_state *c;
107 struct nmb_name called, calling;
108 char *server_n;
109 char *server;
110 struct in_addr ip;
111 extern struct in_addr ipzero;
113 server = share+2;
114 share = strchr(server,'\\');
115 if (!share) return NULL;
116 *share = 0;
117 share++;
119 server_n = server;
121 ip = ipzero;
123 make_nmb_name(&calling, "masktest", 0x0, "");
124 make_nmb_name(&called , server, 0x20, "");
126 again:
127 ip = ipzero;
129 /* have to open a new connection */
130 if (!(c=cli_initialise(NULL)) || (cli_set_port(c, 139) == 0) ||
131 !cli_connect(c, server_n, &ip)) {
132 DEBUG(0,("Connection to %s failed\n", server_n));
133 return NULL;
136 if (!cli_session_request(c, &calling, &called)) {
137 DEBUG(0,("session request to %s failed\n", called.name));
138 cli_shutdown(c);
139 if (strcmp(called.name, "*SMBSERVER")) {
140 make_nmb_name(&called , "*SMBSERVER", 0x20, "");
141 goto again;
143 return NULL;
146 DEBUG(4,(" session request ok\n"));
148 if (!cli_negprot(c)) {
149 DEBUG(0,("protocol negotiation failed\n"));
150 cli_shutdown(c);
151 return NULL;
154 if (!got_pass) {
155 char *pass = getpass("Password: ");
156 if (pass) {
157 pstrcpy(password, pass);
161 if (!cli_session_setup(c, username,
162 password, strlen(password),
163 password, strlen(password),
164 workgroup)) {
165 DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
166 return NULL;
170 * These next two lines are needed to emulate
171 * old client behaviour for people who have
172 * scripts based on client output.
173 * QUESTION ? Do we want to have a 'client compatibility
174 * mode to turn these on/off ? JRA.
177 if (*c->server_domain || *c->server_os || *c->server_type)
178 DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
179 c->server_domain,c->server_os,c->server_type));
181 DEBUG(4,(" session setup ok\n"));
183 if (!cli_send_tconX(c, share, "?????",
184 password, strlen(password)+1)) {
185 DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
186 cli_shutdown(c);
187 return NULL;
190 DEBUG(4,(" tconx ok\n"));
192 return c;
195 static char *resultp;
197 void listfn(file_info *f, const char *s)
199 if (strcmp(f->name,".") == 0) {
200 resultp[0] = '+';
201 } else if (strcmp(f->name,"..") == 0) {
202 resultp[1] = '+';
203 } else {
204 resultp[2] = '+';
209 static void testpair(struct cli_state *cli1, struct cli_state *cli2,
210 char *mask, char *file)
212 int fnum;
213 fstring res1, res2;
214 char *res3;
215 static int count;
217 count++;
219 fstrcpy(res1, "---");
220 fstrcpy(res2, "---");
222 fnum = cli_open(cli1, file, O_CREAT|O_TRUNC|O_RDWR, 0);
223 if (fnum == -1) {
224 DEBUG(0,("Can't create %s on cli1\n", file));
225 return;
227 cli_close(cli1, fnum);
229 fnum = cli_open(cli2, file, O_CREAT|O_TRUNC|O_RDWR, 0);
230 if (fnum == -1) {
231 DEBUG(0,("Can't create %s on cli2\n", file));
232 return;
234 cli_close(cli2, fnum);
236 resultp = res1;
237 cli_list(cli1, mask, aHIDDEN | aDIR, listfn);
239 res3 = reg_test(mask, file);
241 resultp = res2;
242 cli_list(cli2, mask, aHIDDEN | aDIR, listfn);
244 if (showall || strcmp(res1, res2)) {
245 DEBUG(0,("%s %s %s %d mask=[%s] file=[%s]\n",
246 res1, res2, res3, count, mask, file));
249 cli_unlink(cli1, file);
250 cli_unlink(cli2, file);
253 static void test_mask(int argc, char *argv[],
254 struct cli_state *cli1, struct cli_state *cli2)
256 pstring mask, file;
257 int l1, l2, i, j, l;
258 int mc_len = strlen(maskchars);
259 int fc_len = strlen(filechars);
261 cli_mkdir(cli1, "masktest");
262 cli_mkdir(cli2, "masktest");
264 cli_unlink(cli1, "\\masktest\\*");
265 cli_unlink(cli2, "\\masktest\\*");
267 if (argc >= 2) {
268 while (argc >= 2) {
269 pstrcpy(mask,"\\masktest\\");
270 pstrcpy(file,"\\masktest\\");
271 pstrcat(mask, argv[0]);
272 pstrcat(file, argv[1]);
273 testpair(cli1, cli2, mask, file);
274 argv += 2;
275 argc -= 2;
277 goto finished;
280 for (i=0; standard_masks[i]; i++) {
281 for (j=0; standard_files[j]; j++) {
282 pstrcpy(mask,"\\masktest\\");
283 pstrcpy(file,"\\masktest\\");
284 pstrcat(mask, standard_masks[i]);
285 pstrcat(file, standard_files[j]);
286 testpair(cli1, cli2, mask, file);
290 while (1) {
291 l1 = 1 + random() % 20;
292 l2 = 1 + random() % 20;
293 pstrcpy(mask,"\\masktest\\");
294 pstrcpy(file,"\\masktest\\");
295 l = strlen(mask);
296 for (i=0;i<l1;i++) {
297 mask[i+l] = maskchars[random() % mc_len];
299 mask[l+l1] = 0;
301 for (i=0;i<l2;i++) {
302 file[i+l] = filechars[random() % fc_len];
304 file[l+l2] = 0;
306 if (strcmp(file+l,".") == 0 ||
307 strcmp(file+l,"..") == 0 ||
308 strcmp(mask+l,"..") == 0) continue;
310 testpair(cli1, cli2, mask, file);
313 finished:
314 cli_rmdir(cli1, "\\masktest");
315 cli_rmdir(cli2, "\\masktest");
319 static void usage(void)
321 printf(
322 "Usage:\n\
323 masktest //server1/share1 //server2/share2 [options..]\n\
324 options:\n\
325 -U user%%pass\n\
326 -s seed\n\
327 -f filechars (default %s)\n\
328 -m maskchars (default %s)\n\
329 -a show all tests\n\
331 This program tests wildcard matching between two servers. It generates\n\
332 random pairs of filenames/masks and tests that they match in the same\n\
333 way on two servers\n\
335 filechars, maskchars);
338 /****************************************************************************
339 main program
340 ****************************************************************************/
341 int main(int argc,char *argv[])
343 char *share1, *share2;
344 struct cli_state *cli1, *cli2;
345 extern char *optarg;
346 extern int optind;
347 extern FILE *dbf;
348 int opt;
349 char *p;
350 int seed;
352 setlinebuf(stdout);
354 dbf = stderr;
356 if (argv[1][0] == '-' || argc < 3) {
357 usage();
358 exit(1);
361 share1 = argv[1];
362 share2 = argv[2];
364 all_string_sub(share1,"/","\\",0);
365 all_string_sub(share2,"/","\\",0);
367 setup_logging(argv[0],True);
369 argc -= 2;
370 argv += 2;
372 TimeInit();
373 charset_initialise();
375 if (getenv("USER")) {
376 pstrcpy(username,getenv("USER"));
379 seed = time(NULL);
381 while ((opt = getopt(argc, argv, "U:s:hm:f:a")) != EOF) {
382 switch (opt) {
383 case 'U':
384 pstrcpy(username,optarg);
385 p = strchr(username,'%');
386 if (p) {
387 *p = 0;
388 pstrcpy(password, p+1);
389 got_pass = 1;
391 break;
392 case 's':
393 seed = atoi(optarg);
394 break;
395 case 'h':
396 usage();
397 exit(1);
398 case 'm':
399 maskchars = optarg;
400 break;
401 case 'f':
402 filechars = optarg;
403 break;
404 case 'a':
405 showall = 1;
406 break;
407 default:
408 printf("Unknown option %c (%d)\n", (char)opt, opt);
409 exit(1);
413 argc -= optind;
414 argv += optind;
416 DEBUG(0,("seed=%d\n", seed));
417 srandom(seed);
419 cli1 = connect_one(share1);
420 if (!cli1) {
421 DEBUG(0,("Failed to connect to %s\n", share1));
422 exit(1);
425 cli2 = connect_one(share2);
426 if (!cli2) {
427 DEBUG(0,("Failed to connect to %s\n", share2));
428 exit(1);
432 test_mask(argc, argv, cli1, cli2);
434 return(0);