1# A library of commonly used functions written in expect.
2# Copyright Brad Henry <brad@samba.org> 2006
3# Released under the GNU GPL version 3 or later.
4
5# This function maps a drive letter to a share point.
6proc map_share { remote_prompt share_drive sharepoint username domain password } {
7	set default_err_str "Unknown error in function map_share"
8	set err_str $default_err_str
9
10	set cmd "net use $share_drive $sharepoint $password /USER:$username@$domain\r\n"
11	send $cmd
12
13	expect {
14		"The command completed successfully." {
15			expect_prompt $remote_prompt
16			set err_str "OK"
17		} \
18		"The local device name is already in use." {
19			expect_prompt $remote_prompt
20			set err_str "The device name $share_drive is already in use"
21		} \
22		"The network name cannot be found." {
23			expect_prompt $remote_prompt
24			set err_str "Sharepoint $sharepoint could not be found"
25		} \
26		timeout {
27			set err_str "Function map_share timed out while mapping $share_drive to $sharepoint"
28		}
29	}
30	return $err_str
31}
32
33# This function unmaps a drive letter from a share point.
34proc unmap_share { remote_prompt share_drive } {
35	set default_err_str "Unknown error in function unmap_share"
36	set err_str $default_err_str
37
38	set cmd "net use $share_drive /DELETE\r\n"
39	send $cmd
40
41	expect {
42		"was deleted successfully." {
43			expect_prompt $remote_prompt
44			set err_str "OK"
45		} \
46		"NET HELPMSG 2250" {
47			expect_prompt $remote_prompt
48			set err_str "The network connection could not be found while unmapping $share_drive"
49		} \
50		timeout {
51			set err_str "Function unmap_share timed out while unmapping $share_drive"
52		}
53	}
54	return $err_str
55}
56
57# This function uses xcopy to copy a text file from one location on the
58# remote windows host to another.
59proc xcopy_file { remote_prompt in_filename out_filename xcopy_options } {
60	set default_err_str "Unknown error in function xcopy_file"
61	set err_str $default_err_str
62
63	set cmd "xcopy $in_filename $out_filename $xcopy_options\r\n"
64	send $cmd
65
66	expect {
67		"(F = file, D = directory)? " {
68			set cmd "F\r\n"
69			send $cmd
70			expect {
71				"1 File(s) copied\r\n\r\n" {
72					expect_prompt $remote_prompt
73					set err_str "OK"
74				} \
75				"0 File(s) copied\r\n\r\n" {
76					expect_prompt $remote_prompt
77					set err_str $default_err_str
78				} \
79				timeout {
80					set err_str "Function xcopy_file has timed out while copying $in_filename"
81				}
82			}
83		} \
84		"1 File(s) copied\r\n\r\n" {
85			expect_prompt $remote_prompt
86			set err_str "OK"
87		} \
88		"0 File(s) copied\r\n\r\n" {
89			expect_prompt $remote_prompt
90			set err_str $default_err_str
91		} \
92		timeout {
93			set err_str "Function xcopy_file timed out while copying $in_filename"
94		}
95	}
96	return $err_str
97}
98
99# This function creates a temporary file on the remote windows host.
100# The file contents are populated by a recursive directory listing of
101# the windows %HOMEDRIVE%.
102proc create_tmp_file { remote_prompt filename } {
103	set default_err_str "Unknown error in function create_tmp_file"
104	set err_str $default_err_str
105
106	set cmd "dir %HOMEDRIVE%\\ /S > $filename\r\n"
107	send $cmd
108	expect {
109		$remote_prompt {
110			set err_str "OK"
111		} \
112		timeout {
113			set err_str "Function create_tmp_file timed out while creating $filename"
114		}
115	}
116	return $err_str
117}
118
119# This function compares two files on the remote windows host.
120proc compare_files { remote_prompt file1 file2 } {
121	set default_err_str "Unknown error in function compare_files"
122	set err_str $default_err_str
123
124	set cmd "fc $file1 $file2\r\n"
125	send $cmd
126	expect {
127		"FC: no differences encountered\r\n\r\n\r\n" {
128			expect_prompt $remote_prompt
129			set err_str "OK"
130		} \
131		"\*\*\*\*\* $file1" {
132			expect_prompt $remote_prompt
133			set err_str "Files $file1 and $file2 differ"
134		} \
135		"\*\*\*\*\* $file2" {
136			expect_prompt $remote_prompt
137			set err_str "Files $file1 and $file2 differ"
138		} \
139		timeout {
140			set err_str "Function compare_files timed out while comparing files $file1 and $file2"
141		}
142	}
143	return $err_str
144}
145
146# This function deletes a file on the remote windows host.
147proc delete_file { remote_prompt filename } {
148	set default_err_str "Unknown error in function delete_file"
149	set err_str $default_err_str
150
151	set cmd "del $filename\r\n"
152	send $cmd
153	expect {
154		"Could Not" {
155			expect_prompt $remote_prompt
156			set err_str $default_err_str
157		} \
158		$remote_prompt {
159			set err_str "OK"
160		} \
161		timeout {
162			set err_str "Function delete_file timed oout while deleting $filename"
163		}
164	}
165	return $err_str
166}
167
168# This function copies a text file over telnet from the local unix host
169# to the remote windows host.
170proc copy_file { remote_prompt in_filename out_filename } {
171	set default_err_str "Unknown error in function copy_file"
172	set err_str $default_err_str
173
174	# The octal ASCII code for Control-Z is 032.
175	set CTRLZ \032
176
177	# Open local file and read contents.
178	set in_file [open $in_filename r]
179	set in_data [read $in_file]
180
181	# Initiate copy on remote host.
182	set cmd "copy con $out_filename\r\n"
183	send $cmd
184
185	# Separate $in_data into lines and send to remote host.
186	set out_data [split $in_data "\n"]
187	foreach out_line $out_data {
188		send $out_line
189		# We might as well do a unix -> windows line conversion.
190		send "\r\n"
191		# Are we overwriting an existing file?
192		# If so, exit so we can handle it.
193		expect {
194			"(Yes/No/All)" {
195				send "NO\r\n"
196				expect_prompt $remote_prompt
197				set err_str "File exists"
198			} \
199			$out_line {
200				set err_str "OK"
201			} \
202			timeout {
203				set err_str "Function copy_file timed out while copying $in_filename"
204			}
205		}
206		if { $err_str != "OK" } {
207			return $err_str
208		} else {
209			set err_str $default_err_str
210		}
211	}
212
213	# ^Z\r to complete the transfer.
214	send $CTRLZ
215	send "\r"
216	expect {
217		"file(s) copied." {
218			set err_str [expect_prompt $remote_prompt]
219		} \
220		$remote_prompt {
221			set err_str $default_err_str
222		} \
223		timeout {
224			expect_prompt $remote_prompt
225			set err_str "Function copy_file timed out while finishing copy of $in_filename"
226		}
227	}
228	return $err_str
229}
230
231# This function waits for the command prompt and reports an error on
232# timeout.
233proc expect_prompt { remote_prompt } {
234	set default_err_str "Unknown error occurred while waiting for the command prompt"
235	set err_str $default_err_str
236
237	expect {
238		$remote_prompt {
239			set err_str "OK"
240		} \
241		timeout {
242			set err_str "Timeout occurred while waiting for the command prompt"
243		}
244	}
245	return $err_str
246}
247
248# This function will create a telnet login shell to $remote_host as $username.
249# If expected dialogue is not received, return with a specific error if one
250# is recognized. Otherwise return a generic error indicating the function
251# name.
252proc telnet_login { remote_prompt remote_host username password } {
253
254	set default_err_str "Unknown error in function telnet_login"
255	set err_str $default_err_str
256
257	set cmd "telnet $remote_host\r"
258	send $cmd
259	expect {
260		"login: " {
261			set err_str "OK"
262		} \
263		"Connection refused" {
264			set err_str "Connection refused"
265		} \
266		"No route to host" {
267			set err_str "No route to host"
268		} \
269		timeout {
270			set err_str "Function telnet_login timed out while waiting for the login prompt"
271		}
272	}
273	if { $err_str != "OK" } {
274		# Return because something unexpected happened.
275		return $err_str
276	} else {
277		# Reset err_str
278		set err_str $default_err_str
279	}
280
281	set cmd "$username\r"
282	send $cmd
283	expect {
284		"password: " {
285			set err_str "OK"
286		} \
287		timeout {
288			set err_str "Function telnet_login timed out while waiting for the password prompt"
289		}
290	}
291	if { $err_str != "OK" } {
292		return $err_str
293	} else {
294		set err_str $default_err_str
295	}
296
297	set cmd "$password\r"
298	send $cmd
299	expect {
300		$remote_prompt {
301			set err_str "OK"
302		} \
303		"Login Failed" {
304			set err_str "Telnet login failed"
305		} \
306		timeout {
307			set err_str "Function telnet_login timed out while waiting for the command prompt"
308		}
309	}
310	return $err_str
311}
312
313proc create_directory { remote_prompt sharepath } {
314
315	set default_err_str "Unknown error in function create_directory"
316	set err_str $default_err_str
317
318	set cmd "mkdir $sharepath\r\n"
319	send $cmd
320	expect  {
321		"already exists" {
322			expect_prompt $remote_prompt
323			set err_str "Directory already exists"
324		} \
325		$remote_prompt {
326			set err_str "OK"
327		} \
328		timeout {
329			expect_prompt $remote_prompt
330			set err_str "Timeout reached starting create_directory."
331		}
332	}
333	return $err_str
334}
335
336proc delete_directory { remote_prompt sharepath } {
337
338	set default_err_str "Unknown error in function delete_directory"
339	set err_str $default_err_str
340
341	set cmd "rmdir /S /Q $sharepath\r\n"
342	send $cmd
343	expect {
344		"Access is denied." {
345			expect_prompt $remote_prompt
346			set err_str "Directory access is denied"
347		} \
348		$remote_prompt {
349			set err_str "OK"
350		} \
351		timeout {
352			expect_prompt $remote_prompt
353			set err_str "Timeout reached in delete_directory"
354		}
355	}
356	return $err_str
357}
358
359proc create_share { remote_prompt username sharepath sharename } {
360
361	set default_err_str "Unknown error in function create_share"
362	set err_str $default_err_str
363
364	set cmd "net share $sharename=$sharepath /GRANT:$username,FULL\r\n"
365	send $cmd
366	expect {
367		"was shared successfully." {
368			set err_str [expect_prompt $remote_prompt]
369		} \
370		"NET HELPMSG 2118." {
371			expect_prompt $remote_prompt
372			set err_str "The name has already been shared"
373		} \
374		$remote_prompt {
375			set err_str $default_err_str
376		} \
377		timeout {
378			expect_prompt $remote_prompt
379			set err_str "Timeout reached in create_share"
380		}
381	}
382	return $err_str
383}
384
385proc delete_share { remote_prompt sharename } {
386
387	set default_err_str "Unknown error in function delete_share"
388	set err_str $default_err_str
389
390	set cmd "net share $sharename /DELETE\r\n"
391	send $cmd
392	expect {
393		"was deleted successfully." {
394			set err_str [expect_prompt $remote_prompt]
395		} \
396		"does not exist." {
397			expect_prompt $remote_prompt
398			set err_str "The share does not exist"
399		} \
400		$remote_prompt {
401			set err_str $default_err_str
402		} \
403		timeout {
404			expect_prompt $remote_prompt
405			set err_str "Timeout reached in delete_share"
406		}
407	}
408	return $err_str
409}
410
411proc delete_hosts_entry { remote_prompt hosts_file_path backup_hosts_filename } {
412
413	set default_err_str "Unknown error in function delete_hosts_entry"
414	set err_str $default_err_str
415
416	set cmd "cd $hosts_file_path\r\n"
417	send $cmd
418	expect {
419		"." {
420			expect_prompt $remote_prompt
421			set err_str $default_err_str
422		} \
423		$remote_prompt {
424			set err_str "OK"
425		} \
426		timeout {
427			expect_prompt $remote_prompt
428			set err_str "Timeout reached in delete_hosts_entry"
429		}
430	}
431	if { $err_str != "OK" } {
432		return $err_str
433	} else {
434		set err_str $default_err_str
435	}
436
437	set cmd "move /Y $backup_hosts_filename hosts\r\n"
438	send $cmd
439	expect {
440		"1 file(s) moved." {
441			set err_str [expect_prompt $remote_prompt]
442		} \
443		"cannot find the file specified." {
444			expect_prompt $remote_prompt
445			set err_str "File not found"
446		} \
447		$remote_prompt {
448			set err_str $default_err_str
449		} \
450		timeout {
451			expect_prompt $remote_prompt
452			set err_str "Function delete_hosts_entry timed out while renaming $backup_hosts_filename"
453		}
454	}
455	return $err_str
456}
457
458proc create_hosts_entry { remote_prompt hosts_file_path hostname ip \
459				backup_hosts_filename } {
460
461	set default_err_str "Unknown error in function create_hosts_entry"
462	set err_str $default_err_str
463
464	set cmd "cd $hosts_file_path\r\n"
465	send $cmd
466	expect	{
467		"." {
468			expect_prompt $remote_prompt
469			set err_str $default_err_str
470		} \
471		$remote_prompt {
472			set err_str "OK"
473		} \
474		timeout {
475			expect_prompt $remote_prompt
476			set err_str "Timeout reached in create_hosts_entry"
477		}
478	}
479	if { $err_str != "OK" } {
480		return $err_str
481	} else {
482		set err_str $default_err_str
483	}
484
485	set cmd "copy /Y hosts $backup_hosts_filename\r\n"
486	send $cmd
487	expect	{
488		"1 file(s) copied." {
489			set err_str [expect_prompt $remote_prompt]
490		} \
491		"cannot find the file specified." {
492			expect_prompt $remote_prompt
493			set err_str "File not found."
494		} \
495		$remote_prompt {
496			set err_str $default_err_str
497		} \
498		timeout {
499			expect_prompt $remote_prompt
500			set err_str "Function create_hosts_entry timed out while copying hosts file"
501		}
502	}
503	if { $err_str != "OK" } {
504		return $err_str
505	} else {
506		set err_str $default_err_str
507	}
508
509	set cmd "echo $ip     $hostname     #smbtorture host. >> hosts\r\n"
510	send $cmd
511	expect	{
512		$remote_prompt {
513			set err_str "OK"
514		} \
515		timeout {
516			expect_prompt $remote_prompt
517			set err_str "Function create_hosts timed out while updating hosts file"
518		}
519	}
520	return $err_str
521}
522