" " + yellow("--md5sum") + " - append md5sum\n" + \
" " + yellow("--type") + " - prepend file type"
def shortHelp(self):
- return yellow("<local-opts> ") + green("pkgspec") + " - list files owned by " + green("pkgspec")
+ return yellow("<local-opts> ") + teal("pkgspec") + " - list files owned by " + teal("pkgspec")
class CmdListBelongs(Command):
break
def shortHelp(self):
- return yellow("<local-opts> ") + green("query") + " - list all packages owning " + green("file")
+ return yellow("<local-opts> ") + teal("file") + " - list all packages owning " + teal("file")
def longHelp(self):
return "List all packages owning a particular file" + \
"\n" + \
turquoise("Note: ") + "Normally, only one package will own a file. If multiple packages own the same file, it usually consitutes a problem, and should be reported.\n" + \
"\n" + \
"Syntax:\n" + \
- " " + green("belongs") + yellow(" <local-opts> ") + green("filename") + \
+ " " + green("belongs") + yellow(" <local-opts> ") + teal("filename") + \
"\n" + \
yellow("<local-opts>") + " is either of: \n" + \
" " + yellow("-c, --category cat") + " - only search in category " + yellow("cat") + "\n" + \
" " + yellow("-e, --earlyout") + " - stop when first match found\n"
-
-class CmdListDepends(Command):
- """List all packages directly or indirectly depending on pkgQuery"""
- pass
class CmdDisplayUSEs(Command):
"""Advanced report of a package's USE flags"""
- pass
+ def __init__(self):
+ self.default_opts = {
+ }
+ def parseArgs(self, args):
+
+ query = ""
+ need_help = 0
+ opts = self.default_opts
+ skip = 0
+
+ for i in xrange(len(args)):
+
+ if skip:
+ skip -= 1
+ continue
+ x = args[i]
+
+ if x in ["-h","--help"]:
+ need_help = 1
+ break
+ else:
+ query = x
+
+ if need_help or query == "":
+ print self.longHelp()
+ sys.exit(-1)
+
+ return (query, opts)
+
+ def perform(self, args):
+
+ (query, opts) = self.parseArgs(args)
+
+ matches = gentoolkit.find_packages(query)
+
+ useflags = gentoolkit.settings["USE"].split()
+ usedesc = {}
+ uselocaldesc = {}
+
+ # Load global USE flag descriptions
+ try:
+ fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.desc")
+ usedesc = {}
+ for line in fd.readlines():
+ if line[0] == "#":
+ continue
+ fields = line.split(" - ")
+ if len(fields) == 2:
+ usedesc[fields[0].strip()] = fields[1].strip()
+ except IOError:
+ if Config["verbosityLevel"] >= 5:
+ print "Warning: Could not load USE flag descriptions from " + gentoolkit.settings["PORTDIR"] + "/profiles/use.desc"
+
+ # Load local USE flag descriptions
+ try:
+ fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.local.desc")
+ for line in fd.readlines():
+ if line[0] == "#":
+ continue
+ fields = line.split(" - ")
+ if len(fields) == 2:
+ catpkguse = re.search("([a-z]+-[a-z]+/.*):(.*)", fields[0])
+ if catpkguse:
+ if not uselocaldesc.has_key(catpkguse.group(1).strip()):
+ uselocaldesc[catpkguse.group(1).strip()] = {catpkguse.group(2).strip() : fields[1].strip()}
+ else:
+ uselocaldesc[catpkguse.group(1).strip()][catpkguse.group(2).strip()] = fields[1].strip()
+ except IOError:
+ if Config["verbosityLevel"] >= 5:
+ print "Warning: Could not load USE flag descriptions from " + gentoolkit.settings["PORTDIR"] + "/profiles/use.desc"
+
+ print "[ Colour Code : " + green("set") + " " + red("unset") + " ]"
+ print "[ Legend : (U) Col 1 - Current USE flags ]"
+ print "[ : (I) Col 2 - Installed With USE flags ]"
+
+ # Iterate through matches, printing a report for each package
+ for p in matches:
+ if not p.is_installed():
+ continue
+
+ bestver = p.get_cpv()
+ iuse = p.get_env_var("IUSE")
+
+ if iuse: usevar = iuse.split()
+ else: usevar = []
+
+ inuse = []
+ used = p.get_use_vars().split()
+
+ # store (inuse, inused, flag, desc)
+ output = []
+
+ for u in usevar:
+ inuse = 0
+ inused = 0
+ try:
+ desc = usedesc[u]
+ except KeyError:
+ try:
+ desc = uselocaldesc[p][u]
+ except KeyError:
+ desc = ""
+
+ if u in useflags: inuse = 1
+ if u in used: inused = 1
+
+ output.append((inuse, inused, u, desc))
+
+ # pretty print
+ if output:
+ print
+ print white(" U I ") + "[ Found these USE variables in : " + white(bestver) + " ]"
+ maxflag_len = 0
+ for inuse, inused, u, desc in output:
+ if len(u) > maxflag_len:
+ maxflag_len = len(u)
+
+ for inuse, inused, u, desc in output:
+ flag = ["-","+"]
+ colour = [red, green]
+ if inuse != inused:
+ print yellow(" %s %s" % (flag[inuse], flag[inused])),
+ else:
+ print " %s %s" % (flag[inuse], flag[inused]),
+
+ print colour[inuse](u.ljust(maxflag_len)),
+
+ # print description
+ if desc:
+ print ":", desc
+ else:
+ print ": unknown"
+ else:
+ print "[ No USE flags found for :", white(p.get_cpv()), "]"
+ def shortHelp(self):
+ return yellow("<local-opts> ") + teal("pkgspec") + " - display USE flags for " + teal("pkgspec")
+ def longHelp(self):
+ return "Display USE flags for a given package\n" + \
+ "\n" + \
+ "Syntax:\n" + \
+ " " + green("uses") + yellow(" <local-opts> ") + teal("pkgspec") + \
+ "\n" + \
+ yellow("<local-opts>") + " is either of: \n"
+
class CmdDisplayDepGraph(Command):
"""Display tree graph of deps for pkgQuery"""
return pkgtbl
def shortHelp(self):
- return yellow("<local-opts> ") + green("pkgspec") + " - display a dependency tree for " + green("pkgspec")
+ return yellow("<local-opts> ") + teal("pkgspec") + " - display a dependency tree for " + teal("pkgspec")
def longHelp(self):
return "Display a dependency tree for a given package\n" + \
"\n" + \
"Syntax:\n" + \
- " " + green("depgraph") + yellow(" <local-opts> ") + green("pkgspec") + \
+ " " + green("depgraph") + yellow(" <local-opts> ") + teal("pkgspec") + \
"\n" + \
yellow("<local-opts>") + " is either of: \n" + \
" " + yellow("-U, --no-useflags") + " - do not show USE flags\n" + \
" " + yellow("-l, --linear") + " - do not use fancy formatting"
-class CmdDisplayChanges(Command):
- """Display changes for pkgQuery"""
- pass
-
class CmdDisplaySize(Command):
"""Display disk size consumed by a package"""
def __init__(self):
def shortHelp(self):
- return yellow("<local-opts> ") + green("pkgspec") + " - print size of files contained in packages " + green("pkgspec")
+ return yellow("<local-opts> ") + teal("pkgspec") + " - print size of files contained in package " + teal("pkgspec")
def longHelp(self):
return "Print size total size of files contained in a given package" + \
"\n" + \
"Syntax:\n" + \
- " " + green("size") + yellow(" <local-opts> ") + green("pkgspec") + \
+ " " + green("size") + yellow(" <local-opts> ") + teal("pkgspec") + \
"\n" + \
yellow("<local-opts>") + " is either of: \n" + \
" " + yellow("-b, --bytes") + " - report size in bytes\n"
-class CmdCheckIntegrity(Command):
- """Check timestamps and md5sums for files owned by pkgQuery"""
+class CmdDisplayChanges(Command):
+ """Display changes for pkgQuery"""
pass
+class CheckException:
+ def __init__(self, s):
+ self.s = s
+
+class CmdCheckIntegrity(Command):
+ """Check timestamps and md5sums for files owned by pkgspec"""
+ def __init__(self):
+ self.default_opts = {
+ "showSummary" : 1,
+ "showGoodFiles" : 0,
+ "showBadFiles" : 1,
+ "checkTimestamp" : 1,
+ "checkMD5sum": 1
+ }
+
+ def parseArgs(self, args):
+
+ query = ""
+ need_help = 0
+ opts = self.default_opts
+ skip = 0
+
+ for i in xrange(len(args)):
+ if skip:
+ skip -= 1
+ continue
+ x = args[i]
+
+ if x in ["-h","--help"]:
+ need_help = 1
+ break
+ else:
+ query = x
+
+ if need_help or query == "":
+ print self.longHelp()
+ sys.exit(-1)
+
+ return (query, opts)
+
+ def checkMD5sum(self, file):
+ return 1
+
+ def perform(self, args):
+ (query, opts) = self.parseArgs(args)
+
+ matches = gentoolkit.find_packages(query)
+
+ for pkg in matches:
+ if not pkg.is_installed():
+ continue
+ files = pkg.get_contents()
+ for file in files.keys():
+ type = files[file][0]
+ try:
+ st = os.lstat(file)
+ if type == "dir":
+ if not os.path.isdir(file):
+ raise CheckException(file + " exists, but is not a directory")
+ elif type == "obj":
+ mtime = files[file][1]
+ if opts["checkTimestamp"]:
+ if st.st_mtime != int(mtime):
+ raise CheckException(file + (" has wrong mtime (is %d, should be %s)" % (st.st_mtime, mtime)))
+ if opts["checkMD5sum"]:
+ if not self.checkMD5sum(file):
+ raise CheckException(file + " has incorrect md5sum")
+ elif type == "sym":
+ # FIXME: nastry strippery; portage should have this fixed!
+ t = files[file][2]
+ i = t.find("(")
+ target = t[0:i].strip()
+ if not os.path.islink(file):
+ raise CheckException(file + " exists, but is not a symlink")
+ tgt = os.readlink(file)
+ if tgt != target:
+ raise CheckException(file + " does not point to " + target)
+
+ else:
+ print file
+ print files[file]
+ print type
+ raise "Unknown type"
+ except CheckException, (e):
+ print e.s
+ except OSError:
+ print file + " does not exist"
+
+ def shortHelp(self):
+ return teal("pkgspec") + " - check package's files against recorded MD5 sums and timestamps"
+ def longHelp(self):
+ return "Check package's files against recorded MD5 sums and timestamps"
+
class CmdDisplayStatistics(Command):
"""Display statistics about installed and uninstalled packages"""
pass
+class CmdWhich(Command):
+ """Display the filename of the ebuild for a given package
+ that would be used by Portage with the current configuration."""
+ def __init__(self):
+ self.default_opts = {}
+
+ def parseArgs(self, args):
+
+ query = ""
+ need_help = 0
+ opts = self.default_opts
+ skip = 0
+
+ for i in xrange(len(args)):
+
+ if skip:
+ skip -= 1
+ continue
+ x = args[i]
+
+ if x in ["-h","--help"]:
+ need_help = 1
+ break
+ else:
+ query = x
+
+ if need_help or query == "":
+ print self.longHelp()
+ sys.exit(-1)
+
+ return (query, opts)
+
+ def perform(self, args):
+ (query, opts) = self.parseArgs(args)
+
+ matches = gentoolkit.find_packages(query)
+
+ for pkg in matches:
+ print os.path.normpath(pkg.get_ebuild_path())
+
+ def shortHelp(self):
+ return teal("pkgspec") + " - print full path to ebuild for package " + teal("pkgspec")
+ def longHelp(self):
+ return "Print full path to ebuild for a given package"
+
+class CmdListGLSAs(Command):
+ """List outstanding GLSAs."""
+ pass
+
+class CmdListDepends(Command):
+ """List all packages directly or indirectly depending on pkgQuery"""
+ pass
+
class CmdListPackages(Command):
"""List packages satisfying pkgQuery"""
def __init__(self):
print pfxmodes[status] + " " + pkg.get_cpv()
def shortHelp(self):
- return yellow("<local-opts> ") + green("pkgspec") + " - list all packages matching " + green("pkgspec")
+ return yellow("<local-opts> ") + teal("pkgspec") + " - list all packages matching " + teal("pkgspec")
def longHelp(self):
return "List all packages matching a query pattern" + \
"\n" + \
"Syntax:\n" + \
- " " + green("list") + yellow(" <local-opts> ") + green("pkgspec") + \
+ " " + green("list") + yellow(" <local-opts> ") + teal("pkgspec") + \
"\n" + \
yellow("<local-opts>") + " is either of: \n" + \
" " + yellow("-i, --installed") + " - search installed packages (default)\n" + \
"changes": CmdDisplayChanges(),
"size": CmdDisplaySize(),
"check": CmdCheckIntegrity(),
- "stats": CmdDisplayStatistics()
+ "stats": CmdDisplayStatistics(),
+ "glsa": CmdListGLSAs(),
+ "which": CmdWhich()
}
Config = {
(cmd, local_opts) = parseArgs(sys.argv[1:])
if cmd:
cmd.perform(local_opts)
+
CONFDIR="/tmp/moo"
+class Config:
+ pass
+def die(code, msg):
+ sys.stdout.write(msg + "\n")
+ sys.edit(code)
+
def printUsage():
print "Usage: moo <options> [command] <command-options>\n" + \
"Where [command] is one of:\n" + \
pass
def runCmd(cmd):
- print "Executing \"" + cmd + "\""
+ if Config.verbosity > 5:
+ print "Executing \"" + cmd + "\""
v = os.system(cmd)
- print "Result: " + str(v)
+ if Config.verbosity > 5:
+ print "Result: " + str(v)
+ return v
class ProfileHandler:
def __init__(self):
self.broadcast = ""
self.gateway = ""
self.exclusive = "no"
+ self.netmask = ""
+ self.nameserver = ""
ins = open(filename)
for s in ins.readlines():
for x in ["description","ifaceName","ip","broadcast",
- "gateway","exclusive"]:
+ "gateway","exclusive","nameserver","wepkey"]:
if s.find(x+"=") == 0:
val=s.replace(x+"=","").strip()
self.__dict__[x] = val
"ip = " + self.ip + "\n" + \
"broadcast = " + self.broadcast + "\n" + \
"gateway = " + self.gateway + "\n" + \
- "exclusive = " + self.exclusive + "\n"
+ "gateway = " + self.nameserver + "\n" + \
+ "exclusive = " + self.exclusive + "\n"
class Interface:
def __init__(self, name):
self.broadcast = ""
self.ip = ""
self.gateway = ""
+ self.nameserver = ""
+ self.wepkey = ""
self._loadIPV4Info()
def _loadIPV4Info(self):
pass
+ def getNameserver(self):
+ return self.nameserver
def getNetmask(self):
return self.netmask
def getName(self):
return self.name
def getBroadcast(self):
return self.broadcast
+ def getWEPKey(self):
+ return self.wepkey
def getGateway(self):
return self.gateway
+ def setNameserver(self,nameserver):
+ self.nameserver = nameserver
+ def setIP(self, ip):
+ self.ip = ip
+ def setWEPKey(self,key):
+ self.wepkey = key
def setGateway(self,gw):
self.gateway = gw
def setBroadcast(self,broadcast):
os.kill(pid,signal.SIGTERM)
time.sleep(1)
def up(self):
+ options = ""
+
+ if self.wepkey:
+ if runCmd("iwconfig eth1 key " + self.wepkey):
+ die(4, "Failed to set WEP key for " + self.name)
+
if self.ip:
options += self.ip + " "
if self.broadcast:
options += "broadcast " + self.broadcast + " "
if self.netmask:
options += "netmask " + self.netmask + " "
- runCmd("ifconfig " + self.name + " " + options + " up")
+
+ if runCmd("ifconfig " + self.name + " " + options + " up"):
+ die(2, "Failed to bring up " + self.name)
+
if self.gateway:
- runCmd("route add default gw " + self.gateway + " " + self.name)
+ if runCmd("route add default gw " + self.gateway + " " + self.name):
+ die(3, "Failed to set default gateway for " + self.name)
+
+ if self.nameserver:
+ if Config.verbosity > 5:
+ print("Using nameserver " + self.nameserver)
+ try:
+ ous = open("/etc/resolv.conf","w")
+ ous.write("nameserver " + self.nameserver)
+ ous.close()
+ except OSError:
+ die("Failed to set nameserver")
+ if Config.verbosity > 3:
+ print "Brough interface " + self.name + " up"
class InterfaceHandler:
def __init__(self):
if prof.ip == "dhcp":
iface.runDHCP()
else:
- iface.setIPAddr(prof.ip)
+ iface.setIP(prof.ip)
iface.setBroadcast(prof.broadcast)
iface.setNetmask(prof.netmask)
iface.setGateway(prof.gateway)
+ iface.setNameserver(prof.nameserver)
iface.up()
def listProfiles(self,detailed=0):
self.profileHandler.listProfiles(detailed)
-
+
+def initConfig():
+ Config.verbosity = 3
+
def main():
+
+ initConfig()
+
if len(sys.argv) < 2:
printUsage()
sys.exit(1)