#!/usr/bin/python3 import errno import os import sys from sys import stdout from sys import argv import subprocess ##### global data ####### drv_lst = [] #list of removable "sdx" block devices found in /sys/block partition_list0 = [] partition_list1 = [] partition_list2 = [] partition_list3 = [] partition_list4 = [] partition_list5 = [] partition_list6 = [] mounts = [] # list of mounts, indexed by drv_lst vendors = [] models = [] drive_sizes = [] def have_exe(name): try: cp = subprocess.run(name, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError as e: if e.errno == os.errno.ENOENT: return False return(True) def quote_shell(args): return " ".join(quote(arg) for arg in args) def quote_applescript(string): charmap = { "\n": "\\n", "\r": "\\r", "\t": "\\t", "\"": "\\\"", "\\": "\\\\", } return '"%s"' % "".join(charmap.get(char, char) for char in string) def elevate(show_console=True, graphical=False): if os.getuid() == 0: return print("format_fat32 needs to run as root, will ask for password") args = [sys.executable] + sys.argv commands = [] commands.append(["sudo"] + args) for args in commands: try: os.execlp(args[0], *args) except OSError as e: if e.errno != errno.ENOENT or args[0] == "sudo": raise def is_root(): return os.getuid() == 0 #returns list #example= "/proc/mounts" #if error returns len() = 0 def file_read_to_list(fname): lst=[] try: f = open(fname,"r") except IOError: print("failed to open",fname) return('') for l in f: lst.append(l.strip()) f.close() return(lst) #do unix command, returns 0 if error #example cmd = "ls -d /sys/block/*" returns full path of dir entries #example cmd = "ls -w1 /sys/block" returns single dir/file per list entry #if error returns len() = 0 def do_cmd(cmd): lst = [] try: f = os.popen(cmd) except IOError: print("dir_read failed") return('') for l in f.readlines(): lst.append(l.strip()) return(lst) def find_drives(): global drv_lst drv_lst = [] lst = do_cmd("ls -w1 /sys/block") if len(lst) == 0: print("error reading /sys/block") return() print("block devices found=",lst) for blk in lst: if "sd" in blk: # print("found-",blk) pathx = "/sys/block/"+blk+"/removable" rflag = file_read_to_list(pathx) # print("read ",pathx,"got-",rflag) if rflag[0] == '1': # print("found drive") drv_lst.append(blk) return(drv_lst) #find partitions for drive at indx in drv_lst def find_partitions_one_drive(indx): plist=[] cmd = "ls -w1 /sys/block/"+drv_lst[indx] lst = do_cmd(cmd) if len(lst) == 0: print("error reading ",cmd) return() for partit in lst: if drv_lst[indx] in partit: print("found partition ",partit) plist.append(partit) return(plist) def find_all_partitions(): global partition_list0,partition_list1,partition_list2 indx = 0 for drivex in drv_lst: x = find_partitions_one_drive(indx) globals()["partition_list"+str(indx)] = x # print("find_all_partitions found",x) indx = indx + 1 def get_mounts(): global mounts added = 0 for xdrive in drv_lst: m = file_read_to_list("/proc/mounts") # print("len(m)=",len(m)) # print("m=",m) for line in m: if line.find("/dev/"+xdrive) != -1: # print("adding line-",line) #x = line.split() mounts.append(line) # print("len(line)=",len(line),"len(mounts)=",len(mounts)) added = 1 break if added == 0: mounts.append("0") added = 0 def get_drv_model(): for xdrive in drv_lst: m = file_read_to_list("/sys/block/"+xdrive+"/device/vendor") vendors.append(m) m = file_read_to_list("/sys/block/"+xdrive+"/device/model") models.append(m) def get_sizes(): for xdrive in drv_lst: m = file_read_to_list("/sys/block/"+xdrive+"/size") x = int(m[0]) xx = x/2000000 xx = round(xx,0) if xx < 1: z = str(int(xx))+"Megs" else: z = str(int(xx))+"Gigs" drive_sizes.append(z) def get_key(): import tty, termios fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return(ch) def sfdisk_part(y): print("using sfdisk") cmd = "sfdisk --delete /dev/"+str(drv_lst[y]) do_cmd(cmd) cmd = "echo ',,c;' | sfdisk --force /dev/"+str(drv_lst[y]) do_cmd(cmd) cmd = "mkfs.exfat -n fat32 /dev/"+str(drv_lst[y])+"1" do_cmd(cmd) print("drive formatted") def parted_part(y): print("using parted") indx = 1 for partit in globals()["partition_list"+str(y)]: print("/dev/"+str(drv_lst[y])) cmd = "parted -s /dev/"+str(drv_lst[y])+" rm "+str(indx) print(cmd) do_cmd(cmd) indx = indx + 1 cmd = "parted -s /dev/"+str(drv_lst[y])+" mklabel msdos mkpart primary fat32 0 100%" print("cmd=",cmd) do_cmd(cmd) cmd = "mkfs.exfat -n fat32 /dev/"+str(drv_lst[y])+"1" do_cmd(cmd) print("drive formatted") ############# start of execution ################# xmessage = have_exe("xmessage") notify = have_exe("notify-send") if stdout.isatty() == False: # print('The output device is a teletype. Or something like a teletype.') #else: if xmessage == True: os.popen("xmessage -center format-fat32 needs a terminal") elif notify == True: os.popen("notify-send '**whoops** format-fat32 needs a terminal'") sys.exit() try: from shlex import quote except ImportError: from pipes import quote elevate() sfdisk = have_exe(["sfdisk","-V"]) parted= have_exe(["parted","-v"]) mkfs = have_exe(["mkfs.fat","--help"]) #print("xmessage=",xmessage,"notify=",notify,"sfdisk=",sfdisk,"parted=",parted,"mkfs=",mkfs) x = find_drives() #print("drv_lst=",drv_lst) find_all_partitions() #print("partition_list0=",partition_list0) #print("partition_list1=",partition_list1) get_mounts() #print("len(mounts)=",len(mounts)) #print("mounts=",mounts) get_drv_model() #print("vendors=",vendors) #print("models=",models) get_sizes() #print("drive_sizes=",drive_sizes) do_exit = 0 if sfdisk == False and parted == False: print("**** sfdisk or parted programs needed to continue *****") do_exit = 1 if mkfs == False: print("**** the mkfs program is needed to continue *****") do_exit = 1 if do_exit == 1: sys.exit() if len(drv_lst) == 0: print("No removable drives found\nPress any key to continue") get_key() sys.exit() menu = "Enter number of option\n 0 = exit\n" indx = 1 x="" for xdrive in drv_lst: y = str(vendors[indx -1]) z = str(models[indx -1]) w = str(drive_sizes[indx-1]) x = " "+str(indx) +" format "+xdrive+y+z+" size-"+w+"\n" menu = menu + x indx = indx + 1 print(menu) x = get_key() if x == "0": sys.exit() y = int(x) print("unmounting all partition for drive "+str(drv_lst[y-1])+" "+str(globals()["partition_list"+str(y-1)])) for partit in globals()["partition_list"+str(y-1)]: print("/dev/"+str(partit)) do_cmd("umount /dev/"+str(partit)) if sfdisk == True: # sfdisk_part(y-1) #elif partit == True: parted_part(y-1) lst = do_cmd("fdisk -l /dev/"+str(drv_lst[y-1])) print(lst)