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 char *reg_test(char *pattern
, char *file
)
54 pattern
= 1+strrchr(pattern
,'\\');
55 file
= 1+strrchr(file
,'\\');
59 if (strcmp(file
,"..") == 0) file
= ".";
60 if (strcmp(pattern
,".") == 0) return ret
;
62 if (strcmp(pattern
,"") == 0) {
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) {
92 if (regexec(&preg
, file
, 0, NULL
, 0) == 0) {
101 /*****************************************************
102 return a connection to a server
103 *******************************************************/
104 struct cli_state
*connect_one(char *share
)
107 struct nmb_name called
, calling
;
111 extern struct in_addr ipzero
;
114 share
= strchr(server
,'\\');
115 if (!share
) return NULL
;
123 make_nmb_name(&calling
, "masktest", 0x0, "");
124 make_nmb_name(&called
, server
, 0x20, "");
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
));
136 if (!cli_session_request(c
, &calling
, &called
)) {
137 DEBUG(0,("session request to %s failed\n", called
.name
));
139 if (strcmp(called
.name
, "*SMBSERVER")) {
140 make_nmb_name(&called
, "*SMBSERVER", 0x20, "");
146 DEBUG(4,(" session request ok\n"));
148 if (!cli_negprot(c
)) {
149 DEBUG(0,("protocol negotiation failed\n"));
155 char *pass
= getpass("Password: ");
157 pstrcpy(password
, pass
);
161 if (!cli_session_setup(c
, username
,
162 password
, strlen(password
),
163 password
, strlen(password
),
165 DEBUG(0,("session setup failed: %s\n", cli_errstr(c
)));
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
)));
190 DEBUG(4,(" tconx ok\n"));
195 static char *resultp
;
197 void listfn(file_info
*f
, const char *s
)
199 if (strcmp(f
->name
,".") == 0) {
201 } else if (strcmp(f
->name
,"..") == 0) {
209 static void testpair(struct cli_state
*cli1
, struct cli_state
*cli2
,
210 char *mask
, char *file
)
219 fstrcpy(res1
, "---");
220 fstrcpy(res2
, "---");
222 fnum
= cli_open(cli1
, file
, O_CREAT
|O_TRUNC
|O_RDWR
, 0);
224 DEBUG(0,("Can't create %s on cli1\n", file
));
227 cli_close(cli1
, fnum
);
229 fnum
= cli_open(cli2
, file
, O_CREAT
|O_TRUNC
|O_RDWR
, 0);
231 DEBUG(0,("Can't create %s on cli2\n", file
));
234 cli_close(cli2
, fnum
);
237 cli_list(cli1
, mask
, aHIDDEN
| aDIR
, listfn
);
239 res3
= reg_test(mask
, file
);
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
)
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\\*");
269 pstrcpy(mask
,"\\masktest\\");
270 pstrcpy(file
,"\\masktest\\");
271 pstrcat(mask
, argv
[0]);
272 pstrcat(file
, argv
[1]);
273 testpair(cli1
, cli2
, mask
, file
);
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
);
291 l1
= 1 + random() % 20;
292 l2
= 1 + random() % 20;
293 pstrcpy(mask
,"\\masktest\\");
294 pstrcpy(file
,"\\masktest\\");
297 mask
[i
+l
] = maskchars
[random() % mc_len
];
302 file
[i
+l
] = filechars
[random() % fc_len
];
306 if (strcmp(file
+l
,".") == 0 ||
307 strcmp(file
+l
,"..") == 0 ||
308 strcmp(mask
+l
,"..") == 0) continue;
310 testpair(cli1
, cli2
, mask
, file
);
314 cli_rmdir(cli1
, "\\masktest");
315 cli_rmdir(cli2
, "\\masktest");
319 static void usage(void)
323 masktest //server1/share1 //server2/share2 [options..]\n\
327 -f filechars (default %s)\n\
328 -m maskchars (default %s)\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 /****************************************************************************
340 ****************************************************************************/
341 int main(int argc
,char *argv
[])
343 char *share1
, *share2
;
344 struct cli_state
*cli1
, *cli2
;
356 if (argv
[1][0] == '-' || argc
< 3) {
364 all_string_sub(share1
,"/","\\",0);
365 all_string_sub(share2
,"/","\\",0);
367 setup_logging(argv
[0],True
);
373 charset_initialise();
375 if (getenv("USER")) {
376 pstrcpy(username
,getenv("USER"));
381 while ((opt
= getopt(argc
, argv
, "U:s:hm:f:a")) != EOF
) {
384 pstrcpy(username
,optarg
);
385 p
= strchr(username
,'%');
388 pstrcpy(password
, p
+1);
408 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
416 DEBUG(0,("seed=%d\n", seed
));
419 cli1
= connect_one(share1
);
421 DEBUG(0,("Failed to connect to %s\n", share1
));
425 cli2
= connect_one(share2
);
427 DEBUG(0,("Failed to connect to %s\n", share2
));
432 test_mask(argc
, argv
, cli1
, cli2
);