2 Unix SMB/Netbios implementation.
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.
26 extern int DEBUGLEVEL
;
27 static fstring password
;
28 static fstring username
;
29 static fstring workgroup
;
32 static BOOL showall
= False
;
34 static char *maskchars
= "<>\"?*abc.";
35 static char *filechars
= "abcdefghijklm.";
37 char *standard_masks
[] = {"*", "*.", "*.*",
38 ".*", "d2.??", "d2\">>", "??",
40 char *standard_files
[] = {"abc", "abc.", ".abc",
41 "abc.def", "abc.de.f",
48 static BOOL
reg_match_one(char *pattern
, char *file
)
53 pstrcpy(rpattern
, pattern
);
55 if (strcmp(file
,"..") == 0) file
= ".";
56 if (strcmp(rpattern
,".") == 0) return False
;
58 all_string_sub(rpattern
,"\"", ".", 0);
59 all_string_sub(rpattern
,"<", "*", 0);
61 all_string_sub(rpattern
,"*>", "*", 0);
62 all_string_sub(rpattern
,">*", "*", 0);
63 all_string_sub(rpattern
,">", "?", 0);
65 if (is_8_3(file
, False
)) {
66 return fnmatch(rpattern
, file
, 0)==0;
70 mangle_name_83(rfile
);
73 return (fnmatch(rpattern
, file
, 0)==0 ||
74 fnmatch(rpattern
, rfile
, 0)==0);
77 static BOOL
regex_reg_match_one(char *pattern
, char *file
)
83 return fnmatch(pattern
, file
, 0)==0;
85 if (strcmp(file
,"..") == 0) file
= ".";
86 if (strcmp(pattern
,".") == 0) return False
;
88 if (strcmp(pattern
,"") == 0) {
89 if (strcmp(file
,".") == 0) return False
;
93 pstrcpy(rpattern
,"^");
94 pstrcat(rpattern
, pattern
);
96 all_string_sub(rpattern
,".", "[.]", 0);
97 all_string_sub(rpattern
,"?", ".{1}", 0);
98 all_string_sub(rpattern
,"*", ".*", 0);
99 all_string_sub(rpattern
+strlen(rpattern
)-1,">", "([^.]?|[.]?$)", 0);
100 all_string_sub(rpattern
,">", "[^.]?", 0);
102 all_string_sub(rpattern
,"<[.]", ".*[.]", 0);
103 all_string_sub(rpattern
,"<\"", "(.*[.]|.*$)", 0);
104 all_string_sub(rpattern
,"<", "([^.]*|[^.]*[.]|[.][^.]*|[.].*[.])", 0);
105 if (strlen(pattern
)>1) {
106 all_string_sub(rpattern
+strlen(rpattern
)-1,"\"", "[.]?", 0);
108 all_string_sub(rpattern
,"\"", "([.]|$)", 0);
109 pstrcat(rpattern
,"$");
111 /* printf("pattern=[%s] rpattern=[%s]\n", pattern, rpattern); */
113 regcomp(&preg
, rpattern
, REG_ICASE
|REG_NOSUB
|REG_EXTENDED
);
114 ret
= (regexec(&preg
, file
, 0, NULL
, 0) == 0);
121 static char *reg_test(char *pattern
, char *file
)
126 pattern
= 1+strrchr(pattern
,'\\');
127 file
= 1+strrchr(file
,'\\');
129 if (reg_match_one(pattern
, ".")) ret
[0] = '+';
130 if (reg_match_one(pattern
, "..")) ret
[1] = '+';
131 if (reg_match_one(pattern
, file
)) ret
[2] = '+';
136 /*****************************************************
137 return a connection to a server
138 *******************************************************/
139 struct cli_state
*connect_one(char *share
)
142 struct nmb_name called
, calling
;
146 extern struct in_addr ipzero
;
149 share
= strchr(server
,'\\');
150 if (!share
) return NULL
;
158 make_nmb_name(&calling
, "masktest", 0x0);
159 make_nmb_name(&called
, server
, 0x20);
164 /* have to open a new connection */
165 if (!(c
=cli_initialise(NULL
)) || (cli_set_port(c
, 139) == 0) ||
166 !cli_connect(c
, server_n
, &ip
)) {
167 DEBUG(0,("Connection to %s failed\n", server_n
));
171 if (!cli_session_request(c
, &calling
, &called
)) {
172 DEBUG(0,("session request to %s failed\n", called
.name
));
174 if (strcmp(called
.name
, "*SMBSERVER")) {
175 make_nmb_name(&called
, "*SMBSERVER", 0x20);
181 DEBUG(4,(" session request ok\n"));
183 if (!cli_negprot(c
)) {
184 DEBUG(0,("protocol negotiation failed\n"));
190 char *pass
= getpass("Password: ");
192 pstrcpy(password
, pass
);
196 if (!cli_session_setup(c
, username
,
197 password
, strlen(password
),
198 password
, strlen(password
),
200 DEBUG(0,("session setup failed: %s\n", cli_errstr(c
)));
205 * These next two lines are needed to emulate
206 * old client behaviour for people who have
207 * scripts based on client output.
208 * QUESTION ? Do we want to have a 'client compatibility
209 * mode to turn these on/off ? JRA.
212 if (*c
->server_domain
|| *c
->server_os
|| *c
->server_type
)
213 DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
214 c
->server_domain
,c
->server_os
,c
->server_type
));
216 DEBUG(4,(" session setup ok\n"));
218 if (!cli_send_tconX(c
, share
, "?????",
219 password
, strlen(password
)+1)) {
220 DEBUG(0,("tree connect failed: %s\n", cli_errstr(c
)));
225 DEBUG(4,(" tconx ok\n"));
230 static char *resultp
;
232 void listfn(file_info
*f
, const char *s
)
234 if (strcmp(f
->name
,".") == 0) {
236 } else if (strcmp(f
->name
,"..") == 0) {
244 static void testpair(struct cli_state
*cli1
, struct cli_state
*cli2
,
245 char *mask
, char *file
)
254 fstrcpy(res1
, "---");
255 fstrcpy(res2
, "---");
257 fnum
= cli_open(cli1
, file
, O_CREAT
|O_TRUNC
|O_RDWR
, 0);
259 DEBUG(0,("Can't create %s on cli1\n", file
));
262 cli_close(cli1
, fnum
);
264 fnum
= cli_open(cli2
, file
, O_CREAT
|O_TRUNC
|O_RDWR
, 0);
266 DEBUG(0,("Can't create %s on cli2\n", file
));
269 cli_close(cli2
, fnum
);
272 cli_list(cli1
, mask
, aHIDDEN
| aDIR
, listfn
);
274 res3
= reg_test(mask
, file
);
277 cli_list(cli2
, mask
, aHIDDEN
| aDIR
, listfn
);
279 if (showall
|| strcmp(res1
, res3
)) {
282 p
= strrchr(file
,'\\');
284 mangle_name_83(rfile
);
286 DEBUG(0,("%s %s %s %d mask=[%s] file=[%s] mfile=[%s]\n",
287 res1
, res2
, res3
, count
, mask
, file
, rfile
));
290 cli_unlink(cli1
, file
);
291 cli_unlink(cli2
, file
);
294 if (count
% 500 == 0) DEBUG(0,("%d\n", count
));
297 static void test_mask(int argc
, char *argv
[],
298 struct cli_state
*cli1
, struct cli_state
*cli2
)
302 int mc_len
= strlen(maskchars
);
303 int fc_len
= strlen(filechars
);
305 cli_mkdir(cli1
, "masktest");
306 cli_mkdir(cli2
, "masktest");
308 cli_unlink(cli1
, "\\masktest\\*");
309 cli_unlink(cli2
, "\\masktest\\*");
313 pstrcpy(mask
,"\\masktest\\");
314 pstrcpy(file
,"\\masktest\\");
315 pstrcat(mask
, argv
[0]);
316 pstrcat(file
, argv
[1]);
317 testpair(cli1
, cli2
, mask
, file
);
325 for (i
=0; standard_masks
[i
]; i
++) {
326 for (j
=0; standard_files
[j
]; j
++) {
327 pstrcpy(mask
,"\\masktest\\");
328 pstrcpy(file
,"\\masktest\\");
329 pstrcat(mask
, standard_masks
[i
]);
330 pstrcat(file
, standard_files
[j
]);
331 testpair(cli1
, cli2
, mask
, file
);
337 l1
= 1 + random() % 20;
338 l2
= 1 + random() % 20;
339 pstrcpy(mask
,"\\masktest\\");
340 pstrcpy(file
,"\\masktest\\");
343 mask
[i
+l
] = maskchars
[random() % mc_len
];
348 file
[i
+l
] = filechars
[random() % fc_len
];
352 if (strcmp(file
+l
,".") == 0 ||
353 strcmp(file
+l
,"..") == 0 ||
354 strcmp(mask
+l
,"..") == 0) continue;
356 testpair(cli1
, cli2
, mask
, file
);
360 cli_rmdir(cli1
, "\\masktest");
361 cli_rmdir(cli2
, "\\masktest");
365 static void usage(void)
369 masktest //server1/share1 //server2/share2 [options..]\n\
373 -f filechars (default %s)\n\
374 -m maskchars (default %s)\n\
377 This program tests wildcard matching between two servers. It generates\n\
378 random pairs of filenames/masks and tests that they match in the same\n\
379 way on two servers\n\
381 filechars
, maskchars
);
384 /****************************************************************************
386 ****************************************************************************/
387 int main(int argc
,char *argv
[])
389 char *share1
, *share2
;
390 struct cli_state
*cli1
, *cli2
;
397 static pstring servicesf
= CONFIGFILE
;
403 if (argv
[1][0] == '-' || argc
< 3) {
411 all_string_sub(share1
,"/","\\",0);
412 all_string_sub(share2
,"/","\\",0);
414 setup_logging(argv
[0],True
);
420 charset_initialise();
422 lp_load(servicesf
,True
,False
,False
);
425 if (getenv("USER")) {
426 pstrcpy(username
,getenv("USER"));
431 while ((opt
= getopt(argc
, argv
, "U:s:hm:f:a")) != EOF
) {
434 pstrcpy(username
,optarg
);
435 p
= strchr(username
,'%');
438 pstrcpy(password
, p
+1);
458 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
466 DEBUG(0,("seed=%d\n", seed
));
469 cli1
= connect_one(share1
);
471 DEBUG(0,("Failed to connect to %s\n", share1
));
475 cli2
= connect_one(share2
);
477 DEBUG(0,("Failed to connect to %s\n", share2
));
482 test_mask(argc
, argv
, cli1
, cli2
);