More driver cleanup
[yaffs2.git] / direct / test-framework / python / yaffs_browser.py
1 #!/usr/bin/python 
2 ##
3 ## YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 ##
5 ## Copyright (C) 2002-2010 Aleph One Ltd.
6 ##   for Toby Churchill Ltd and Brightstar Engineering
7 ##
8 ## Created by Timothy Manning <timothy@yaffs.net>
9 ##
10 ## This program is free software; you can redistribute it and/or modify
11 ## it under the terms of the GNU General Public License version 2 as
12 ## published by the Free Software Foundation.
13 ##
14
15 import Tkinter as tk
16 from yaffsfs import *
17 #import examples
18 import ctypes
19 from operator import itemgetter
20
21 yaffs_start_up()
22 yaffs_mount("/yaffs2/")
23 root_window =tk.Tk()
24 root_window.title("YAFFS Browser")
25 mount_list_text_variable=tk.StringVar()
26
27 mount_list_text_variable.set("/yaffs2/")
28 current_directory_dict={}
29 open_windows_list=[]
30
31 class editor():
32     yaffs_handle=0
33     file_editor_root =0
34     save_button=[]
35     file_contents=0
36     file_path=0
37     isLink=0
38     def save_file(self):
39         if  self.isLink==True:
40             target_path=self.file_editor_text.get("1.0", tk.END) ##"1.0" is the index of the first line of text
41             target_path=target_path[0:len(target_path)-1]
42             new_path=self.file_path
43             print "creating a symlink \n target:##", target_path, "##"
44             target_file_exists=yaffs_access(target_path, 0) ##yaffs_access will return 0 on success and -1 on failure.
45             if target_file_exists>=0:
46                 ##file exists,create symlink
47                 print "target file exist, creating symlink"
48                 yaffs_unlink(new_path)
49                 output=yaffs_symlink(target_path, new_path)
50                 print "yaffs symlink output=", output
51                 self.file_editor_root.destroy()
52             else :
53                 ##file does not exist
54                 print "target file does not exist, cannot create symlink"
55         else :
56             #global current_directory_dict
57             print "saving the file"
58             print self.file_editor_text.get("1.0", tk.END) ##"1.0" is the index of the first line of text
59             yaffs_lseek(self.yaffs_handle, 0, 0)
60             data_to_be_written=self.file_editor_text.get("1.0", tk.END)
61             print "data to be saved", data_to_be_written
62             length_of_file=len(data_to_be_written)
63             print "length of data to be written",length_of_file 
64             output=yaffs_write(self.yaffs_handle,data_to_be_written , length_of_file)
65             print "output", output
66             yaffs_ftruncate(self.yaffs_handle, length_of_file)
67             yaffs_close(self.yaffs_handle)
68             self.yaffs_handle = yaffs_open(self.file_path,66,0666)
69         load_dir()
70         
71     def __init__(self, isLink=0):
72         global current_directory_dict
73         x=name_list_box.curselection()
74         self.id=int(x[0])
75         self.file_editor_root =tk.Toplevel()
76         self.save_button=tk.Button(self.file_editor_root, text="save", command=self.save_file)
77         self.save_button.pack(fill=tk.BOTH)
78
79         self.file_path=current_directory_dict[self.id]["path"]
80         print "file path", self.file_path
81         self.file_editor_root.title(current_directory_dict[self.id]["path"])
82         self.file_editor_text=tk.Text(self.file_editor_root)
83         self.yaffs_handle = yaffs_open(current_directory_dict[self.id]["path"],66,0666)
84         length_of_file=yaffs_lseek(self.yaffs_handle, 0, 2) ##seeks to the end of the file
85         yaffs_lseek(self.yaffs_handle, 0, 0)## returns the handle to the front of th file
86         print "length of file to be opened:", length_of_file
87         if isLink==True and False ==True : ##this alows the symlink to be edited and is no longer used. to renable it delete "and False ==True"
88             print "opening symlink"
89             self.file_contents=ctypes.create_string_buffer(1000)
90             yaffs_readlink(self.file_path,self.file_contents,1000)
91             self.isLink=True
92         else:
93             print"opening file"
94             self.file_contents=ctypes.create_string_buffer(length_of_file)
95             yaffs_read(self.yaffs_handle,self.file_contents,length_of_file)
96             print "file contents", self.file_contents.raw
97         self.file_editor_text.insert(tk.END, self.file_contents.raw)
98         self.file_editor_text.pack(fill=tk.BOTH)
99         ##self.file_editor_text.bind("<Control-s>", self.save_file)
100         ##doesn't work because it can't pass "self"
101
102 def load_dir():
103     global current_directory_dict
104     print "loading a new directory*******************************************************************"
105     ##deleate current items in text box
106     name_list_box.delete(0, tk.END)
107     current_directory_dict=yaffs_ls(mount_list_text_variable.get())
108     print "new directory", current_directory_dict
109     
110    
111     
112     ##copy directory into file box
113     for x in range(0,len(current_directory_dict)):
114         permissions_string=""
115         if current_directory_dict[x]["permissions"] & yaffs_S_IREAD:
116             permissions_string ='r'
117         else :
118             permissions_string ='-'
119         if current_directory_dict[x]["permissions"] & yaffs_S_IWRITE:
120             permissions_string+='w'
121         else :
122             permissions_string+='-'
123         name_list_box.insert(x,(current_directory_dict[x]["inodes"]+"  "+permissions_string+"  "+ current_directory_dict[x]["type"]+"  "+ current_directory_dict[x]["size"]+"  "+ current_directory_dict[x]["path"]+"  "+current_directory_dict[x]["extra_data"]))
124     name_list_box.grid(column=0, row=1)
125     return current_directory_dict
126     
127 def remount_yaffs():
128     ##this isn't working. somethihg need to be changed in the config of the simulator to release the handle of the emfile
129     print "remounting yaffs"
130     print"unmounting yaffs:", yaffs_unmount("yaffs2/")
131     print "mounting yaffs", yaffs_mount("/yaffs2/")
132     load_dir()
133     
134 def load_file(link=0):
135     global open_windows_list
136     open_windows_list.append(editor(link))
137
138 def load_command(self=0):
139     global current_directory_dictls
140     
141     print "you loaded a file/dir/link"
142     x=name_list_box.curselection()
143     x=int(x[0])
144     print "cursor selection", x
145     print "dict", current_directory_dict
146
147     print "file inode is:", current_directory_dict[x]["inodes"]
148     
149     
150     print "file path is:", current_directory_dict[x]["path"]
151     if current_directory_dict[x]["type"]=="dir":
152         ##open dir
153         print "open directory"
154         mount_list_text_variable.set(current_directory_dict[x]["path"])
155         print mount_list_text_variable.get()
156         print "old directory dict", current_directory_dict
157         #current_directory_dict=load_dir()
158         load_dir()
159
160         print "new directory dict passed back"
161
162     elif current_directory_dict[x]["type"]=="file" :
163         ##open file
164         print "open file"
165         load_file()
166     elif current_directory_dict[x]["type"]=="link": 
167         print "loading a symlink"
168         load_file(1)
169     ##mount_list_text_variable.set(mount_list_text_variable.get()+str(list[0][0]))
170     
171 def back_a_directory(self=0):
172     x=len(mount_list_text_variable.get())
173     string=mount_list_text_variable.get()
174     slashes_id=[]
175     #print "length of path", x 
176     #print "string been sorted:",  string
177     for i in range(0, x):
178         if string[i]=='/':
179             slashes_id.append(i)
180             #print "slash found at:", i
181         
182     print slashes_id
183     ##slashes_id.sort() not needed because the list is already in acending order
184     ##print "sorted",slashes_id
185
186     string=string[0: slashes_id[len(slashes_id)-2]+1]
187     print string
188     mount_list_text_variable.set(string)
189     load_dir()
190
191
192     
193     
194     
195  
196 def yaffs_ls(dname):
197     ls_dict=[]
198
199     if dname[-1] != "/": dname = dname + "/"
200     dc = yaffs_opendir(dname)
201     if dc != 0 :
202         sep = yaffs_readdir(dc)
203         while bool(sep):
204             
205             se = sep.contents
206             fullname = dname + se.d_name
207             st = yaffs_stat_struct()
208             result = yaffs_lstat(fullname,byref(st))
209             #perms = st.st_mode & 0777
210             perms = st.st_mode 
211             ftype = st.st_mode & yaffs_S_IFMT
212             isFile = True if ftype == yaffs_S_IFREG else False
213             isDir  = True if ftype == yaffs_S_IFDIR else False
214             isSymlink= True if ftype == yaffs_S_IFLNK else False
215
216             if isFile :
217                 ls_dict.append ({"type" :"file",  "inodes" :  str(se.d_ino),   "permissions" : perms,  "size": str(st.st_size), "path":  fullname,"extra_data":""})
218                 print "file st.st_mode:", st.st_mode
219
220             elif isDir :
221                 print "dir st.st_mode:", st.st_mode
222
223                 ls_dict.append({"type":"dir", "inodes" :str(se.d_ino), "permissions":perms,"size":"0",   "path": fullname+"/", "extra_data":""})
224             elif isSymlink:
225                 print "symlink st.st_mode:", st.st_mode
226                 file_contents=ctypes.create_string_buffer(30)
227                 yaffs_readlink(fullname,file_contents,30)
228                 string=repr(file_contents.value)
229                 print "len of str", len(string)
230 #                string.lstrip()
231
232                 print "string", string, "###"
233
234                 ls_dict.append ({"type" :"link",  "inodes" :  str(se.d_ino),   "permissions" : perms,  "size": str(st.st_size), "path":  fullname, "extra_data":"> "+string})
235
236             else :
237                 print "unknown st.st_mode:", st.st_mode
238                 ls_dict.append({ "type":"Other", "inodes":str(se.d_ino),  "permissions":perms, "size":"0",   "path": fullname,"extra_data":""})
239             sep = yaffs_readdir(dc)
240         yaffs_closedir(dc)
241         return sorted(ls_dict,key=itemgetter("path"))
242     else:
243         print "Could not open directory"
244         return -1
245
246
247 ##toolbar 
248 toolbar_frame=tk.Frame(root_window)
249 button_open=tk.Button(toolbar_frame, command=load_command, text="load")
250 button_open.grid(column=0, row=0)
251 button_back=tk.Button(toolbar_frame, command=back_a_directory, text="back")
252 button_back.grid(column=1, row=0)
253 toolbar_frame.grid(row=0, column=0,  columnspan=3)
254
255 def delete_selected(selected_dir=0):
256     if selected_dir==0:
257         print"using current_directory_dict"
258         global current_directory_dict
259         x=name_list_box.curselection()
260         x=int(x[0])
261         print current_directory_dict[x]["type"]
262         if current_directory_dict[x]["type"]=="file":
263             path=current_directory_dict[x]["path"]
264             path =path
265             output=yaffs_unlink(path)
266             print "unlinking output:", output
267         elif current_directory_dict[x]["type"]=="dir":
268             path=current_directory_dict[x]["path"]
269             inside_dir=yaffs_ls(path)
270             print "files and folder inside dir", inside_dir
271             print "len of dir", len(inside_dir)
272             if inside_dir!=[]: ##if the dir is not empty
273                 ## remove stuff in dir
274                 for i in range(0,len(inside_dir)):
275                     print "calling self*****"
276                     delete_selected(inside_dir[i])
277                 
278             path =path[0:len(path)-1] ##this is to remove the "/" off the end of the of the file 
279             print "removing:", path
280             output=yaffs_rmdir(path)
281             print "rmdir output:", output
282     else :
283         print "using passed dir"
284         print "dir passed", selected_dir
285         current_directory_dict =selected_dir
286
287         print "after copying", current_directory_dict
288         print current_directory_dict["type"]
289         if current_directory_dict["type"]=="file":
290             path=current_directory_dict["path"]
291             path =path
292             output=yaffs_unlink(path)
293             print "unlinking output:", output
294         elif current_directory_dict["type"]=="dir":
295             path=current_directory_dict["path"]
296             inside_dir=yaffs_ls(path)
297             print "files and folder inside dir", inside_dir
298             print "len of dir", len(inside_dir)
299             if inside_dir!=[]: ##if the dir is not empty
300                 ## remove stuff in dir
301                 for i in range(0,len(inside_dir)):
302                     print "calling self*****"
303                     delete_selected(inside_dir[i])
304                 
305             path =path[0:len(path)-1] ##this is to remove the "/" off the end of the of the file 
306             print "removing:", path
307             output=yaffs_rmdir(path)
308             print "rmdir output:", output
309             
310     load_dir()
311
312
313
314 class new_file():
315     path_entry_box=0
316     new_file_window=0
317     def open_the_file(self):
318         global mount_list_text_variable
319         print "trying to create", mount_list_text_variable.get()+self.path_entry_box.get()
320         yaffs_handle=yaffs_open(self.path_entry_box.get(),66,0666)
321         yaffs_close(yaffs_handle)
322         self.new_file_window.destroy()
323         load_dir()
324
325     def cancel(self):
326         ##del self
327         self.new_file_window.destroy()
328     def __init__(self):
329         global mount_list_text_variable
330         self.new_file_window =tk.Toplevel(takefocus=True)
331         path_frame=tk.Frame(self.new_file_window)
332         path_label=tk.Label(path_frame, text="file path")
333         path_label.pack(side=tk.LEFT)
334         text=tk.StringVar()
335         text.set(mount_list_text_variable.get())
336         print "############################",mount_list_text_variable.get()
337         self.path_entry_box= tk.Entry(path_frame, textvariable=text)
338         self.path_entry_box.pack(side=tk.RIGHT)
339         path_frame.pack()
340         button_frame=tk.Frame(self.new_file_window)
341         create_button=tk.Button(button_frame, text="Create", command=self.open_the_file)
342         create_button.pack(side=tk.LEFT)
343         cancel_button=tk.Button(button_frame, text="Cancel", command=self.cancel)
344         cancel_button.pack(side=tk.RIGHT)
345         button_frame.pack()
346
347 class new_folder():
348     path_entry_box=0
349     new_folder_window=0
350     def create_the_folder(self):
351         global mount_list_text_variable
352         print "trying to create", mount_list_text_variable.get()+self.path_entry_box.get()
353         yaffs_mkdir(self.path_entry_box.get(),0666)
354         self.new_folder_window.destroy()
355
356         load_dir()
357
358     def cancel(self):
359         ##del self
360         self.new_folder_window.destroy()
361     def __init__(self):
362         global mount_list_text_variable
363         self.new_folder_window =tk.Toplevel(takefocus=True)
364         path_frame=tk.Frame(self.new_folder_window)
365         path_label=tk.Label(path_frame, text="directory path")
366         path_label.pack(side=tk.LEFT)
367         text=tk.StringVar()
368         text.set(mount_list_text_variable.get())
369         print "############################",mount_list_text_variable.get()
370         self.path_entry_box= tk.Entry(path_frame, textvariable=text)
371         self.path_entry_box.pack(side=tk.RIGHT)
372         path_frame.pack()
373         button_frame=tk.Frame(self.new_folder_window)
374         create_button=tk.Button(button_frame, text="Create", command=self.create_the_folder)
375         create_button.pack(side=tk.LEFT)
376         cancel_button=tk.Button(button_frame, text="Cancel", command=self.cancel)
377         cancel_button.pack(side=tk.RIGHT)
378         button_frame.pack()
379
380
381 class new_symlink():
382     path_entry_box=0
383     target_text=0
384     new_text=0
385     new_file_window=0
386     def create_the_symlink(self):
387         global mount_list_text_variable
388         ##check the symlink's target is a file.
389         target_path=self.target_text.get()
390         new_path=self.new_text.get()
391         print "creating a symlink \n target:", target_path
392         target_file_exists=yaffs_access(target_path, 0) ##yaffs_access will return 0 on success and -1 on failure.
393         if target_file_exists>=0:
394             ##file exists,create symlink
395             print "target file exist, creating symlink"
396             yaffs_symlink(target_path, new_path)
397             self.new_file_window.destroy()
398         else :
399             ##file does not exist
400             print "target file does not exist, cannot create symlink"
401         load_dir()
402
403     def cancel(self):
404         ##del self
405         self.new_file_window.destroy()
406     def __init__(self):
407         global mount_list_text_variable
408         self.new_file_window =tk.Toplevel(takefocus=True)
409         target_frame=tk.Frame(self.new_file_window)
410         target_label=tk.Label(target_frame, text="target")
411         target_label.pack(side=tk.LEFT)
412         self.target_text=tk.StringVar()
413         self.target_text.set(mount_list_text_variable.get())
414         #print "############################",mount_list_text_variable.get()
415         self.target_entry_box= tk.Entry(target_frame, textvariable=self.target_text)
416         self.target_entry_box.pack(side=tk.RIGHT)
417         target_frame.pack()
418         
419         new_frame=tk.Frame(self.new_file_window)
420         new_label=tk.Label(new_frame, text="file path")
421         new_label.pack(side=tk.LEFT)
422         self.new_text=tk.StringVar()
423         self.new_text.set(mount_list_text_variable.get())
424         #print "############################",mount_list_text_variable.get()
425         self.new_entry_box= tk.Entry(new_frame, textvariable=self.new_text)
426         self.new_entry_box.pack(side=tk.RIGHT)
427         new_frame.pack()
428         
429         button_frame=tk.Frame(self.new_file_window)
430         create_button=tk.Button(button_frame, text="Create", command=self.create_the_symlink)
431         create_button.pack(side=tk.LEFT)
432         cancel_button=tk.Button(button_frame, text="Cancel", command=self.cancel)
433         cancel_button.pack(side=tk.RIGHT)
434         button_frame.pack()
435
436
437
438 class new_hardlink():
439     path_entry_box=0
440     target_text=0
441     new_text=0
442     new_file_window=0
443     def create_the_hardlink(self):
444         global mount_list_text_variable
445         ##check the symlink's target is a file.
446         target_path=self.target_text.get()
447         new_path=self.new_text.get()
448         print "creating a hardlink \n target:", target_path
449         target_file_exists=yaffs_access(target_path, 0) ##yaffs_access will return 0 on success and -1 on failure.
450         if target_file_exists>=0:
451             ##file exists,create symlink
452             print "target file exist, creating hardlink"
453             yaffs_link(target_path, new_path)
454             self.new_file_window.destroy()
455         else :
456             ##file does not exist
457             print "target file does not exist, cannot create hardlink"
458         load_dir()
459
460     def cancel(self):
461         ##del self
462         self.new_file_window.destroy()
463     def __init__(self):
464         global mount_list_text_variable
465         self.new_file_window =tk.Toplevel(takefocus=True)
466         target_frame=tk.Frame(self.new_file_window)
467         target_label=tk.Label(target_frame, text="target")
468         target_label.pack(side=tk.LEFT)
469         self.target_text=tk.StringVar()
470         self.target_text.set(mount_list_text_variable.get())
471         #print "############################",mount_list_text_variable.get()
472         self.target_entry_box= tk.Entry(target_frame, textvariable=self.target_text)
473         self.target_entry_box.pack(side=tk.RIGHT)
474         target_frame.pack()
475         
476         new_frame=tk.Frame(self.new_file_window)
477         new_label=tk.Label(new_frame, text="file path")
478         new_label.pack(side=tk.LEFT)
479         self.new_text=tk.StringVar()
480         self.new_text.set(mount_list_text_variable.get())
481         #print "############################",mount_list_text_variable.get()
482         self.new_entry_box= tk.Entry(new_frame, textvariable=self.new_text)
483         self.new_entry_box.pack(side=tk.RIGHT)
484         new_frame.pack()
485         
486         button_frame=tk.Frame(self.new_file_window)
487         create_button=tk.Button(button_frame, text="Create", command=self.create_the_hardlink)
488         create_button.pack(side=tk.LEFT)
489         cancel_button=tk.Button(button_frame, text="Cancel", command=self.cancel)
490         cancel_button.pack(side=tk.RIGHT)
491         button_frame.pack()
492
493
494 ##mount list entry box init
495 mount_list_frame=tk.Frame(root_window)
496 mount_list_label=tk.Label(mount_list_frame, text="mount list")
497 mount_list_label.pack(side=tk.RIGHT)
498
499 mount_list_entry_box= tk.Entry(mount_list_frame,textvariable=mount_list_text_variable)
500 mount_list_entry_box.pack(side=tk.RIGHT)
501 mount_list_frame.grid(row=1, column=0, columnspan=2)
502
503
504 list_frame=tk.Frame(root_window)
505 name_list_box=tk.Listbox(list_frame,exportselection=0, height=30, width=80)
506 load_dir()
507 list_frame.grid(sticky=tk.W+tk.E+tk.N+tk.S)
508
509 name_list_box.bind("<Double-Button-1>", load_command)
510
511 browser_menu_bar=tk.Menu(root_window)
512 browser_file_menu=tk.Menu(browser_menu_bar)
513
514 browser_file_menu.add_command(label="Reload", command=load_dir)
515 browser_file_menu.add_command(label="Remount yaffs", command=remount_yaffs)
516
517 #browser_file_menu.add_command(label="Open")
518 #browser_file_menu.add_command(label="Save")
519 browser_menu_bar.add_cascade(label="File", menu=browser_file_menu)
520 root_window.config(menu=browser_menu_bar)
521
522
523 browser_edit_menu=tk.Menu(browser_menu_bar)
524
525 browser_edit_menu.add_command(label="New File", command=new_file)
526 browser_edit_menu.add_command(label="New Folder", command=new_folder)
527 browser_edit_menu.add_command(label="New Symlink", command=new_symlink)
528 browser_edit_menu.add_command(label="New Hardlink", command=new_hardlink)
529
530
531 browser_edit_menu.add_command(label="delete selected", command=delete_selected)
532 browser_menu_bar.add_cascade(label="Edit", menu=browser_edit_menu)
533
534
535
536
537
538
539 root_window.mainloop()
540
541 print"unmounting yaffs:", yaffs_unmount("yaffs2/")
542
543