#! /usr/bin/env python import getopt, sys, os, cPickle, string from time import asctime, localtime def usage(): print """ Installation Utility 0.0.2 Copyright 2002 Emanuele Tatti This program is released under GPL >= 2 Usage: instutil [OPTION] Options -h, --help Print this message. -s, --sources Install from sources ("make install") and save in a file information about the program -i, --with-check Install with checkinstall (if present). -l, --list Show a list of programs installed from sources. -u, --uninstall Remove a package installed from source trying with "make uninstall". You have to use the name you chose during installation. -c, --complete Run configure, make, make install. To give options to ./configure simply append them to -c or --complete without "--", for example # instutil -c prefix=/usr enable-feature -v, --version Print version. """ def version(): print "Installation utility 0.0.2" def list_installed(): "Print a list of installed packages from ~/.instutil_list" try: ilist = open(list_path,"r") except IOError: print "Database Packages database not found" sys.exit(2) try: i = 0 print while i != "EOF": packet_info = cPickle.load(ilist) print packet_info["name"],packet_info["version"]," -- ",packet_info["desc"]," Time:",packet_info["time"] print i = packet_info ilist.close() except EOFError: pass def update(pack,ver): "Simply remove the old and install the new one" print "Package is being updated..." print "Removing old package" uninstall(pack) print "Old package removed" print "Installing..." if os.system("make install") == 0: print "Package updated!" #Installation time is updated time = asctime(localtime()) #Source directory is updted idir = os.path.abspath("./") else: print "instutil: error during installation!!!" sys.exit() temp_list = os.tempnam() buffer = open(temp_list,"w") old_list = open(list_path,"r") print "instutil: packages database is being updated..." try: packet_info = cPickle.load(old_list) name = packet_info["name"] while name != pack: cPickle.dump(packet_info,buffer) packet_info = cPickle.load(old_list) name = packet_info["name"] except EOFError: print "Error: could not find package in the database\nProbably the file is changed during operation!" packet_info["time"] = time packet_info["dir"] = idir #Package version is updated packet_info["version"] = ver cPickle.dump(packet_info,buffer) try: packet_info = cPickle.load(old_list) name = packet_info["name"] while name != pack: cPickle.dump(packet_info,buffer) packet_info = cPickle.load(old_list) name = packet_info["name"] except EOFError: pass old_list.close() buffer.close() os.remove(list_path) os.rename(temp_list,list_path) print "Database updated!" def delete_uninstalled(packet): "delete from database the package you have uninstalled" temp_list = os.tempnam() list_buffer = open(temp_list,"w") old_list = open(list_path,"r") print "Packages database is being updated..." packet_info = cPickle.load(old_list) try: while packet_info != packet: cPickle.dump(packet_info,buffer) packet_info = cPickle.load(old_list) except EOFError: print "Error: could not find uninstalled package in the database\nProbably the file is changed during operation!" #this cycle is repeated to include items after the uninstalled package try: packet_info = cPickle.load(old_list) except EOFError: pass try: while packet_info != packet: cPickle.dump(packet_info,buffer) packet_info = cPickle.load(old_list) except EOFError: pass old_list.close() list_buffer.close() os.remove(list_path) os.rename(temp_list,list_path) print "Database updated!" sys.exit() def uninstall(package): "check the source directory of the given package and then execute \"make uninstall\"" try: ilist = open(list_path,"r") except IOError: print "instutil: database not found" sys.exit(2) name = "" while name != package: try: packet_info = cPickle.load(ilist) name = packet_info["name"] except EOFError: print "instutil: package not found" sys.exit() ilist.close() path = packet_info["dir"] cd_to_path = "cd "+path os.system(cd_to_path) if os.system("make uninstall") == 0: print "instutil: uninstalled with success" return packet_info else: print "instutil: error during \"make uninstall\"" def see_info(info): "Let you see package information" print "\nPackage information\n\n[1] Name: ",info["name"],"\n[2] Version: ",info["version"],"\n[3] Description: ",info["desc"],"\n[4] Installation time: ",info["time"],"\n[5] Source directory: ",info["dir"],"\n\n" def modify_info(info): "Let you modify packade information" print "You can choose a number or type \"a\" to accept." ans = raw_input(">>> ") while ans != "1" and ans != "2" and ans != "3" and ans != "4" and ans != "5" and ans != "a": print "\nInvalid value\n" ans = raw_input(">>> ") while ans != "a": if ans == "1": print "\nType a new name" name = raw_input(">>> ") while check(name,info["version"]) == 1 or 0: print "Name already in use" name = raw_input("Type a new name\n>>> ") info["name"] = name see_info(info) elif ans == "2": print "\nType a new version" version = raw_input(">>> ") info["version"] = version see_info(info) elif ans == "3": print "\nType a new description" desc = raw_input(">>> ") info["desc"] = desc see_info(info) elif ans == "4": print "\nType a new Installation Time\nWarning! You should use the same format" time = raw_input(">>> ") info["time"] = time see_info(info) elif ans == "5": print "\nType a new source directory\nWarning! Instutil use this information to uninstall packages!" idir = raw_input(">>> ") info["dir"] = idir see_info(info) print "\nChoose another number or [a]ccept" ans = raw_input(">>> ") print "\nInformation accepted!\nBye!\n" return info def check(pack,ver): "check if the given package is alredy present in database" if os.access(list_path,os.R_OK) == 1: ilist = open(list_path,"r") name = "" try: while name != pack: packet_info = cPickle.load(ilist) name = packet_info["name"] except EOFError: pass ilist.close() else: #Check if a newer version is already installed if packet_info["version"] >= ver: return 1 else: return 0 ilist.close() else: pass def install_complete(opts): "run configure and make" configure = "./configure"+opts print "configuring with: #"+configure if os.system(configure) == 0: print "Configured with success" print "Running make..." else: "instutil: error during configuration.\nExiting..." sys.exit() if os.system("make") == 0: "instutil: compiled with success" install_sources() sys.exit() else: print "instutil: failed to compile!" sys.exit() def install_sources(): "Install with make install and update database" idir = os.path.abspath("./") complete_name = os.path.basename(idir) i = string.find(complete_name,"-") name = complete_name[:i] version = complete_name[i+1:] while check(name,version) == 0: if raw_input("There is an older version of the program in database\nDo you want to update? [y/n] ") == "y": update(name,version) sys.exit() else: print "\nChoose another name\n" name = raw_input(">>> ") check(name,version) while check(name,version) == 1: print "\nA newer or equal version of",name,"is already installed!" ans = raw_input("You can [a]bort, [d]owngrade package or [r]ename: [a/d/r] ") if ans == "a": print "\nBye!\n" sys.exit() elif ans == "d": update(name,version) sys.exit() elif ans == "r": name = raw_input(">>> ") check(name,version) print "Installing sources..." if os.system("make install") == 0: pass else: print "Installazione terminata con un errore" sys.exit(2) print "\nInsert a description\n" desc = raw_input(">>> ") time = asctime(localtime()) packet_info = {"name":name,"desc":desc,"time":time,"dir":idir,"version":version} see_info(packet_info) info = modify_info(packet_info) if os.access(list_path,os.R_OK): ilist = open(list_path,"a") else: print "Packages DATABASE not found!!!\nA new database is being created..." ilist = open(list_path,"w") print "Database created!" cPickle.dump(info,ilist) ilist.close() if __name__=="__main__": home = os.path.expandvars("$HOME") #Define the path of instutil database list_path = home + "/.instutil_list" try: opts, args = getopt.getopt(sys.argv[1:], "ihvslcu", ["help","version", "sources", "with-check", "uninstall", "complete", "list"]) except getopt.GetoptError: # print help information and exit: usage() sys.exit(2) for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() if o in ("-v", "--version"): version() sys.exit() if o in ("-l", "--list"): list_installed() sys.exit() if o in ("-c", "--complete"): conf_params = "" for arg in args: # Add to the given parameters "--" conf_params = conf_params+" --"+arg install_complete(conf_params) sys.exit() if o in ("-s", "--sources"): install_sources() sys.exit(2) if o in ("-i", "--with-check"): if os.system("checkinstall make\ install") == 0: print "instutil: installed with success" sys.exit() else: print "instutil: errore during installation\ninstutil: Probably checkinstall is not installed or in not included in your PATH" sys.exit() if o in ("-u", "--uninstall"): for arg in args: try: delete_uninstalled(uninstall(arg)) sys.exit() except ValueError: print "Nome pacchetto non valido" sys.exit() arg = raw_input("Scrivi il pacchetto che vuoi disintallare\n>>> ") try: delete_uninstalled(uninstall(arg)) sys.exit() except ValueError: print "Nome pacchetto non valido" sys.exit() usage() sys.exit()