#
# Copyright Saul Youssef, January, 2005
#
from Abort import *
import sys,os,string,commands,copy,time,popen2,cPickle,pwd,grp,socket,anydbm,shutil
version = '3.29'
oversion = '3.19'
version_extra = ''
pacmanDir = 'o..pacman..o'
try:
pac_anchor = os.getcwd()
if os.environ.has_key('PWD'): pwd_anchor = os.environ['PWD']
else: pwd_anchor = ''
except OSError:
print 'Current working directory does not exist.'
sys.exit(1)
os.environ['PAC_ANCHOR'] = pac_anchor
pre_316_database = 0
def baseErrorMessage(): return string.strip(str(sys.exc_info()[1]))
def sublist(a,b): return sublistEQ(a,b,lambda x,y: x==y)
def sublistEQ(a,b,eq):
aa = a[:]; bb = b[:]
while len(aa)>0 and len(bb)>0:
x = aa.pop()
while len(bb)>0:
y = bb.pop()
if eq(x,y): break
return len(aa)==0
def shellHeader(csh,sh,py,pl,ksh):
lines = ['#','#-- Setup script made by Pacman '+version+' and is often regenerated. DO NOT EDIT',"#"]
for line in lines:
csh.write(line+'\n')
sh .write(line+'\n')
py .write(line+'\n')
pl .write(line+'\n')
ksh.write(line+'\n')
csh.write('#\n')
csh.write('#-- begin pre-setup\n')
csh.write('#\n')
csh.write('setenv PAC_ANCHOR "%s"\n' % pac_anchor)
csh.write('if (-d "${PAC_ANCHOR}/pre-setup") then\n')
csh.write(' foreach PACMANi (`/usr/bin/env find "${PAC_ANCHOR}/pre-setup" -maxdepth 1 -type f -name \'*.csh\' | sort`)\n')
csh.write(' source "${PACMANi}"\n')
csh.write(' end\n')
csh.write(' unsetenv PACMANi\n')
csh.write('endif\n')
csh.write('#\n')
csh.write('#-- end pre-setup\n')
csh.write('#\n')
sh.write('#\n')
sh.write('#-- begin pre-setup\n')
sh.write('#\n')
sh.write('export PAC_ANCHOR="%s"\n' % pac_anchor)
sh.write('if [ -d "${PAC_ANCHOR}/pre-setup" ]; then\n')
sh.write(' for PACMANi in `/usr/bin/env find "${PAC_ANCHOR}/pre-setup" -maxdepth 1 -type f -name \'*.sh\' | sort`; do\n')
sh.write(' source "${PACMANi}"\n')
sh.write(' done\n')
sh.write(' unset PACMANi\n')
sh.write('fi\n')
sh.write('#\n')
sh.write('#-- end pre-setup\n')
sh.write('#\n')
def shellFooter(csh,sh,py,pl,ksh):
csh.write('#\n')
csh.write('#-- begin post-setup\n')
csh.write('#\n')
csh.write('setenv PAC_ANCHOR "%s"\n' % pac_anchor)
csh.write('if (-d "${PAC_ANCHOR}/post-setup") then\n')
csh.write(' foreach PACMANi (`/usr/bin/env find "${PAC_ANCHOR}/post-setup" -maxdepth 1 -type f -name \'*.csh\' | sort`)\n')
csh.write(' source "${PACMANi}"\n')
csh.write(' end\n')
csh.write(' unsetenv PACMANi\n')
csh.write('endif\n')
csh.write('#\n')
csh.write('#-- end post-setup\n')
csh.write('#\n')
sh.write('#\n')
sh.write('#-- begin post-setup\n')
sh.write('#\n')
sh.write('export PAC_ANCHOR="%s"\n' % pac_anchor)
sh.write('if [ -d "${PAC_ANCHOR}/post-setup" ]; then\n')
sh.write(' for PACMANi in `/usr/bin/env find "${PAC_ANCHOR}/post-setup" -maxdepth 1 -type f -name \'*.sh\' | sort`; do\n')
sh.write(' source "${PACMANi}"\n')
sh.write(' done\n')
sh.write(' unset PACMANi\n')
sh.write('fi\n')
sh.write('#\n')
sh.write('#-- end post-setup\n')
sh.write('#\n')
def forall(x,f):
q = 1
for xx in x:
if not f(xx):
q = 0
exit
return q
def exists(x,f):
q = 0
for xx in x:
if f(xx):
q = 1
exit
return q
class Set: pass
# def __eq__(self,x): abort('Missing == in Set.')
class PreOrder(Set):
def __le__(self,x): abort('Missing __le__ in PreOrder.')
def __ge__(self,x): return x<=self
def __lt__(self,x): return self<=x and not self==x
def __gt__(self,x): return self>=x and not self==x
class PartialOrder(Set):
def __le__(self,x): abort('Missing __le__ in PreOrder.')
def __eq__(self,x): return x<=self and self<=x
def __ge__(self,x): return x<=self
def __lt__(self,x): return self<=x and not self==x
def __gt__(self,x): return self>=x and not self==x
class PreOrderAlpha(PreOrder):
def __init__(self,*x): self._list = [xx for xx in x]
def __len__(self): return len(self._list)
def __le__(self,x): return self._list <= x._list
class PreOrderVector(PreOrder):
def __init__(self,*x): self._list = [xx for xx in x]
def __len__(self): return len(self._list)
def __le__(self,x):
return len(self)==len(x) and forall(range(len(self)),lambda i: self._list[i]<=x._list[i])
class PrintOut:
def __repr__(self): abort('Missing __repr__ function in Set.')
def display(self,ind=0):
print ind*' '+`self`
class Monoid(Set):
def __add__(self,x): abort('Missing + in Monoid.')
class List(Monoid):
def __getitem__(self,i): abort('Missing index in List object.')
def __len__ (self): abort('Missing len in List object.')
def append (self,x): abort('Missing append in List.')
def extend (self,xs):
for x in xs: self.append(x)
def pop (self,i): abort('Missing pop in List.')
def empty (self):
while len(self)>0: self.pop(0)
class ShellOut:
def shellOut(self,csh,sh,py,pl,ksh): abort('Missing shellOut in ShellOut.')
def cwdd():
try:
c = os.getcwd()
except OSError:
c = '- undefined -'
return c
def get(path):
try:
f = open(path,'r')
obj = cPickle.load(f)
f.close()
except(IOError,OSError):
abort("Failure reading from file ["+path+"].")
return obj
class IOAble:
def put(self,path):
try:
removeFile(path)
f = open(path,'w')
cPickle.dump(self,f)
f.close()
except (IOError,OSError):
abort("Failure writing to file ["+path+"].")
class HtmlOut(Set,PrintOut):
def htmlLine(self,w): self.htmlOut(w)
class Reason(Set,HtmlOut,IOAble):
def __init__(self,reason='ok',flag=-1):
if flag==-1:
self._reason = reason
else:
if flag!=0: self._reason = reason
else: self._reason = 'ok'
def __repr__(self): return self._reason
def __eq__(self,x): return self._reason == x._reason
def _display(self,indent=0): self.display(indent)
def display(self,indent=0):
if not self.ok():
if hasattr(self,'_package'): print (indent*' ')+'Error in package ['+self._package._spec.name+']:'
print indent*' '+' '+`self`
def isNull(self): return self._reason=='ok'
def ok(self): return self.isNull()
def reason(self,reas): self._reason = reas
def append(self,r): self._reason = r._reason
def htmlOut(self,w,bullet=1): w.text(`self`)
def require(self):
if not self.ok():
abort(`self`)
else:
return 1
def inquire(self):
if not self.ok(): self.display()
return self.ok()
def _packages(self,ps):
if hasattr(self,'_package'):
if not self._package._spec in [p._spec for p in ps]: ps.append(self._package)
if isinstance(self,AllReason):
for r in self._reasons: r._packages(ps)
class AllReason(Reason):
headline0 = 'All of the following are problems:'
def __init__(self,headline='All of the following are problems:'):
self._reasons = []
self.headline = headline
def __repr__(self):
if self.ok(): return 'ok'
else:
s = self.headline+' '
for r in self._reasons:
s = s + `r` + ' '
return s
def __len__(self): return len(self._reasons)
def display(self,indent=0):
self._display(indent)
ps = []
self._packages(ps)
for p in ps:
if hasattr(p,'_optionErrorMessage'): lines = p._optionErrorMessage()
else : lines = []
for line in lines: print indent*' '+line
L = []
for p in ps:
if hasattr(p,'_cacheErrorMessage'):
lines = p._cacheErrorMessage()
if not lines in L: L.append(lines)
for lines in L:
for line in lines: print indent*' '+line[:-1]
# for p in ps:
# if hasattr(p,'_cacheErrorMessage'): lines = p._cacheErrorMessage()
# else : lines = []
# for line in lines: print indent*' '+line[:-1]
def _display(self,indent=0):
if self.ok(): print indent*' '+'ok'
else:
if self.headline=='' or self.headline=='All of the following are problems:':
for r in self._reasons: r._display(indent)
else:
print indent*' '+self.headline
for r in self._reasons: r._display(indent+4)
def reason(self,reas):
if reas!='ok' and reas!='': self._reasons.append(Reason(reas))
def append(self,r):
if not r.ok():
self._reasons.append(r)
def isNull(self): return len(self._reasons)==0
def htmlOut(self,w,bullet=1):
if len(self)==0:
w.text('ok')
elif len(self)==1 and self.headline==self.headline0:
self._reasons[0].htmlOut(w)
else:
w.text(self.headline); w.cr()
w.text('
')
count = 0
for r in self._reasons:
count = count + 1
r.htmlOut(w)
if count!=len(self._reasons): w.text('
')
w.text('
'); w.cr()
def flatten(self):
reasonLists = []
if self.headline != 'All of the following are problems:':
reasonLists.append(Reason(self.headline))
for r in self._reasons:
if hasattr(r,'_reasons'): reasonLists.extend(r.flatten())
else: reasonLists.append(r)
return reasonLists
def nodups(self):
rl = self.flatten()
return removedups(rl,lambda x,y: x==y)
def reasonDisplay(reason,mode=0):
if not reason.ok() or mode:
r = AllReason()
r.append(reason)
rl = r.nodups()
for rr in rl: print rr
if len(rl)==0: print 'ok'
class ExistsReason(AllReason):
headline = 'One of the following prevents installation:'
def allReason(L,f):
reasons = AllReason()
for x in L: reasons.append(f(x))
return reasons
def allReasonQ(L,f):
reason = Reason()
for x in L:
reason = f(x)
if not reason.ok(): break
return reason
def allReasonQB(L,f):
reason = Reason()
for i in range(len(L)-1,-1,-1):
reason = f(L[i])
if not reason.ok(): break
return reason
def existsReason(L,f):
reasons = ExistsReason()
for x in L:
r = f(x)
if r.ok(): reasons = ExistsReason(); break
else: reasons.append(r)
return reasons
def existsReason2(L,f):
reasons = ExistsReason()
ex = 0
for x in L:
r = f(x)
if not r.ok(): reasons.append(r)
else: ex = 1
if ex: return ExistsReason()
else: return reasons
class RememberReason:
def __init__(self,f):
self._f = f
self._tested = 0
self._reason = Reason()
def rememberReason(self):
if not self._tested:
self._reason = self._f()
self._tested = 1
return self._reason
def currentReason (self):
self._tested = 0
return self.rememberReason()
def reset(self):
self._tested = 0
def multiTry(f,maxTry=3):
r = f()
f_try = 1
while not r.ok() and f_try0:
x = l.pop(0)
if cls==[]: cls. append([x])
elif self.equiv(cls[-1][0],x): cls[-1].append( x )
else: cls. append([x])
return cls
class Clusters:
def __init__(self,items): self.__items = items
def cluster(self,equiv):
c = []
while len(self.__items)>0:
x = self.__items.pop()
cc = [x]; remains = []
for y in self.__items:
if equiv(x,y): cc.append(y)
else: remains.append(y)
self.__items = remains[:]
c.append(cc)
return c
def removedups(l,equiv):
l2 = []
for ll in l:
allneq = 1
for x in l2:
if equiv(x,ll): allneq = 0; break
if allneq: l2.append(ll)
return l2
def removeDups(l):
l2 = []
for ll in l:
allneq = 1
for x in l2:
if x==ll: allneq = 0; break
if allneq: l2.append(ll)
return l2
def sort(l,le):
got_one = 1
while got_one:
got_one = 0
for i in range(len(l)-1):
if not le(l[i],l[i+1]):
temp = l[i+1]; l[i+1] = l[i]; l[i] = temp
got_one = 1
def transitiveClosure(x,y,E):
got_one = 0
for e in E:
if e[0]==x:
if e[1]==y:
got_one = 1
else:
F = E[:]; F.remove(e)
got_one = transitiveClosure(e[0],y,F) or transitiveClosure(e[1],y,F)
if got_one: break
return got_one
def prefix(path):
if '.' in path:
l = string.split(path,'.')
s = ''
for i in range(len(l)-1):
s = s + l[i] + '.'
return s
else:
return path
def joinurl(head,tail):
if tail=='': return head
else:
if head[-1]=='/' and tail[0]=='/': return head+tail[1:]
elif head[-1]=='/' and tail[0]!='/': return head+tail
elif head[-1]!='/' and tail[0]=='/': return head+tail
elif head[-1]!='/' and tail[0]!='/': return head+'/'+tail
else: abort('error.')
def ln(filename,host=socket.gethostname(),location=cwdd()):
return str2file(host+'_'+location+'_'+filename)
def removeFile(path):
if os.path.exists(path):
if verbo('io'): print 'Removing ['+path+']...'
try:
os.remove(path)
except OSError:
pass
def removeFiles(*paths):
for path in paths: removeFile(path)
def saveFiles(*paths):
for path in paths: saveFile(path)
def saveFile(path):
if os.path.exists(path):
if verbo('io'): print 'Saving ['+path+']...'
try:
os.system('cp '+path+' '+path+'.sav')
except (OSError,IOError):
print "Can't mv ["+path+"]. Setup scripts not saved."
def writeable(path):
try:
f = open(os.path.join(path,'zxzytmpfoo'),'w')
f.write(' ')
f.close()
removeFile(os.path.join(path,'zxzytmpfoo'))
return 1
except (IOError,OSError):
return 0
def writeAccess(path): return os.access(path,os.W_OK)
def readAccess(path): return os.access(path,os.R_OK)
# The fileInPath function was fixed by Scot Kronenfeld 2/2009
# Previously, with GNU which v2.16 (common in many Linux distros), this function
# would always return true, even if the supplied app was not in the path
#
# Now, the code with crawl through the PATH manually, looking for app, and
# not rely on the system 'which' command
def fileInPath(app):
# verbo.log('shell-all','About to execute [which '+app+']...')
if "PATH" in os.environ:
for directory in os.environ["PATH"].split(os.pathsep):
exe = os.path.join(directory, app)
if os.path.exists(exe) and os.access(exe, os.X_OK):
return Reason()
return Reason("["+app+"] is not in your path.")
else:
status,output = commands.getstatusoutput('which '+app)
if sys.platform[:6]=='cygwin':
return Reason("["+app+"] is not in your path.",string.count(output,'not found')>0)
elif len(output)>2 and output[:2]=='no':
return Reason("["+app+"] is not in your path.")
else:
return Reason()
def appendNew(x,l):
if l.count(x)==0: l.append(x)
class Meter:
def __init__(self,maximum,message='',minimum=0):
self.maximum = maximum
self.minimum = max(minimum,0)
if maximum>minimum and verbo('meter') or verbo('tarfiles'):
if not message=='': print message
sys.stdout.write(" 0 10 20 30 40 50 60 70 80 90 100\n")
sys.stdout.write(" +----+----+----+----+----+----+----+----+----+----+ \n")
sys.stdout.write(" | | | | | | | | | | | ")
def meter(self,count):
if self.maximum>self.minimum and not switch('quiet') and not switch('q'):
fraction = int((float(count)/float(self.maximum))*50.0)
sys.stdout.write('\r #'+'#'*fraction)
if count==self.maximum: sys.stdout.write('\n')
def meter(i,maximum,message='',front=' '):
x = `i`+'/'+`maximum`
maxx = 12
if len(x)=maxline: sys.stdout.write(line[:maxline]+'\r')
else: sys.stdout.write(line+(maxline-len(line))*' '+'\r')
def flash2(line):
sys.stdout.write('\r'+line+'\r')
def niceListOut(l):
count = 0
for x in l:
count = count + 1
sys.stdout.write(x)
if not count==len(l): sys.stdout.write(', ')
def dlMeter(a,b,c):
mil = 1000000.0; k = 1000.0;
meg = float(a)*float(b)/mil; kbytes = float(a)*float(b)/k
if verbo('meter'):
if meg < 2.0:
if min(int(kbytes),int(float(c)/k))==0 and int(float(c)/k)==0:
meter(1,1,'kB downloaded...')
else:
meter(min(int(kbytes),int(float(c)/k)),int(float(c)/k),'kB downloaded...')
else:
meter(min(int(meg),int(float(c)/mil)),int(float(c)/mil), 'MB downloaded...',' ')
def fullpath(p):
if len(p)>0 and p[0]=='$' and os.environ.has_key(p[1:]):
val = os.environ[p[1:]]
else:
val = os.path.abspath(os.path.expanduser(os.path.expandvars(p)))
return val
# return os.path.abspath(os.path.expanduser(os.path.expandvars(p)))
def fullpath2(p):
x = fullpath(p)
if tail(p,'/') and not tail(x,'/'): x = x + '/'
return x
from Abort import *
def abort(message='Unrecoverable error. Contact Saul.'):
raise AbortException,message
def pr(x): x.out(sys.stdout)
def htmlColor(hout,yesno,f):
if yesno:
f.write('')
hout.htmlOut(f)
f.write('')
else:
f.write('')
hout.htmlOut(f)
f.write('')
def htmlColorStr(string,yesno,f):
if yesno:
f.write('')
f.write(string)
f.write('')
else:
f.write('')
f.write(string)
f.write('')
def isUrl(x):
if len(x)>4: return x[0:4]=='http' or x[0:4]=='ftp:'
else: return 0
def fullNonURL(x):
if isUrl(x): return x
else: return fullpath(x)
def isURL(x): return isUrl(x)
def equivURL(x,y): return x==y or x+'/'==y or x==y+'/'
def isPath(x): return not (':' in x or '@' in x or "\\" in x or ' ' in x)
def front(x,s): return len(x)>=len(s) and x[:len(s)]==s[:len(s)]
def phas(d,x):
if d.count(x)>0:
return 1
else:
return 0
def python2():
if sys.version[0]=='2':
return 1
else:
return 0
def shx(str):
if shell()=='sh' or shell()=='ksh':
return string.replace(str,'SHELL','sh')
elif shell()=='csh':
return string.replace(str,'SHELL','csh')
else:
if string.find(str,'SHELL')==-1:
return str
else:
print 'Unknown unix shell.'
sys.exit()
def shell():
try:
x = pwd.getpwnam(getusername())[-1]
if x == '/bin/csh': sh = 'csh'
elif x == '/bin/sh': sh = 'sh'
elif x == '/bin/tcsh': sh = 'csh'
elif x == '/bin/bash': sh = 'sh'
elif x == '/bin/bash2': sh = 'sh'
elif x == '/bin/bsh': sh = 'sh'
elif x == '/bin/ash': sh = 'sh'
elif x == '/bin/ksh': sh = 'ksh'
else: sh = 'sh'
except:
sh = 'sh'
return sh
def qInpath(com):
if python2():
t1,t2,t3 = os.popen3('which '+com)
return t3.readline()==''
else:
return os.system('which '+com) == 0
def parseTarZ(tarZfile):
try:
if sys.platform[:6]=='cygwin':
# f = os.popen('gunzip --stdout '+tarZfile+' | tar -t -f -')
f = os.popen('gunzip --stdout '+tarZfile+' | '+gnuTarName()+' -t -f -')
lines = f.readlines()
if len(lines)>0: line = lines[0]
else: line = ''
f.close()
else:
# if ask('shell-all','About to execute ['+'gunzip --stdout '+tarZfile+' | tar -t -f -'+']. OK?'):
if ask('shell-all','About to execute ['+'gunzip --stdout '+tarZfile+' | '+gnuTarName()+' -t -f -'+']. OK?'):
# verbo.log('shell','gunzip --stdout '+tarZfile+' | tar -t -f -')
verbo.log('shell','gunzip --stdout '+tarZfile+' | '+gnuTarName()+' -t -f -')
# childout,childin,childerr = popen2.popen3('gunzip --stdout '+tarZfile+' | tar -t -f -')
childout,childin,childerr = popen2.popen3('gunzip --stdout '+tarZfile+' | '+gnuTarName()+' -t -f -')
line = childout.readline()
childout.close()
childin.close()
childerr.close()
else:
abort("Permission to execute ["+'gunzip --stdout '+tarZfile+' | tar -t -f -] has been declined.')
except (IOError,OSError):
return Reason('Failure reading ['+tarZfile+'].'),''
if line=='': return Reason('Tarball ['+tarZfile+'] does not untar to a single subdirectory.'),''
else:
got_root,root = parseTarLine(line)
if got_root: return Reason(),root
else: return Reason('Tarball ['+tarZfile+'] does not untar to a single subdirectory.'),''
def parseTar(tarfile):
try:
if sys.platform[:6]=='cygwin':
# f = os.popen('tar -t -f '+tarfile)
f = os.popen(gnuTarName()+' -t -f '+tarfile)
lines = f.readlines()
if len(lines)>0: line = lines[0]
else: line = ''
f.close()
else:
# if ask('shell-all','About to execute ['+'tar -t -f '+tarfile+']. OK?'):
if ask('shell-all','About to execute ['+gnuTarName()+' -t -f '+tarfile+']. OK?'):
verbo.log('shell','tar -t -f '+tarfile)
# childout,childin,childerr = popen2.popen3('tar -t -f '+tarfile)
childout,childin,childerr = popen2.popen3(gnuTarName()+' -t -f '+tarfile)
line = childout.readline()
childout.close()
childin.close()
childerr.close()
else:
abort("Permission to execute ["+'tar -t -f '+tarfile+'] has been declined.')
except (IOError,OSError):
return Reason('Failure reading ['+tarfile+'].'),''
if line=='': return Reason('Tarball ['+tarfile+'] does not untar to a single subdirectory.'),''
else:
got_root,root = parseTarLine(line)
if got_root: return Reason(),root
else: return Reason('Tarball ['+tarfile+'] does not untar to a single subdirectory.'),''
def parseTarLine(line0):
if not '/' in line0:
return 1,fullpath(os.getcwd())
else:
line = line0[:]
while len(line)>1 and line[0]=='.' or line[0]=='/': line = line[1:]
while len(line)>1 and line[-1]=='\n': line = line[:-1]
if string.strip(line)=='': got_root = 0; root = ''
else:
if line[0] in string.printable:
got_root = 1;
line = string.strip(line)
root = string.split(line,'/')[0]
else: got_root = 0; root = ''
return got_root,root
params = filter(lambda x: len(x)>0 and not x[0]=='-' and not x[-6:]=='pacman' and not x[-3:]=='pac',sys.argv)
switches = filter(lambda x: len(x)>0 and x[0]=='-',sys.argv)
def switchItems(sw):
items = []
p2 = sys.argv[:]
while len(p2)>0:
par = p2.pop(0)
if par=='-'+sw:
while len(p2)>0 and len(p2[0])>0 and not p2[0][0]=='-': items.append(p2.pop(0))
return items
def pcl():
s = '% pacman '
for i in range(1,len(sys.argv)):
s = s + ' '+sys.argv[i]
return s
def switchpar(sw):
for s in switches:
if s[:string.find(s,':')]=='-'+sw:
return 1,s[string.find(s,':')+1:]
return 0,''
def switchInt(sw):
q,par = switchpar(sw)
val = 0
if q:
try:
val = int(par)
except ValueError:
abort('Command line error with switch ['+sw+':'+`par`+'].')
return q,val
def switchItem(sw,item):
swq,text = switchpar(sw)
if swq:
return item in string.split(text,',')
else:
return 0
def param(i):
if i < 0:
print 'Hard error.'
sys.exit()
if i>len(params): return ('')
else: return (params[i])
def switch(arg):
return switch0(arg)
# return switch0(arg) or switchpar(arg)[0]
def switch0(arg):
if switches.count('-'+arg)>0: return 1
else: return 0
verbose = switch('v') or switch('verbose')
def intBits(x,nbits):
bits = []
for i in range(nbits):
if (x/2)*2==x: bits.append(0)
else: bits.append(1)
x = x/2
return bits
def bits2Int(bits):
x = 0
p = 0
for i in range(len(bits)):
x = x + bits[i]*(2**i)
return x
def owner(path):
try:
u = user(os.stat(fullpath(path))[4])[0]
except (IOError,OSError):
abort('Error attempting to examine ['+path+'].')
return u
def owner2(path):
reason = Reason()
try:
u = user(os.stat(fullpath(path))[4])[0]
except (IOError,OSError):
u = ''
reason = Reason('Error attempting to examine ['+path+'].')
return reason,u
def getusername():
euid = os.geteuid()
return user(euid)[0]
def user(uid):
try:
username = pwd.getpwuid(uid)
except KeyError:
username = 'unknown'
print 'Warning: unknown userid ['+`uid`+'].'
# abort('No such uid ['+`uid`+'].')
return username
def userids(username):
try:
t = pwd.getpwnam(username)
return 1,t[2],t[3]
except KeyError:
return 0,0,0
def userexists(username):
try:
t = pwd.getpwnam(username)
return 1
except KeyError:
return 0
def groupExists(group):
try:
t = grp.getgrnam(group)
return 1
except KeyError:
return 0
def fncat(a,b):
if a=='':
return b
else:
if a[len(a)-1]=='/':
if b=='':
return (a[:-1])
else:
return (a+b)
else:
return (a+'/'+b)
def tail(str,t):
found = 0
if len(str)>= len(t):
if str[len(str)-len(t):len(str)]==t:
found = 1
return found
def yesdash(s):
if s >= 1: return ('yes')
elif s == 0: return ('-')
else:
print 'Unexpected argument to yesdash.'
print s
sys.exit(1)
def firstLine(path):
r = Reason()
px = fullpath(path)
line = ''
if os.path.exists(px):
try:
f = open(px,'r')
lines = f.readlines()
f.close()
except:
r = Reason("Can't read ["+px+"].")
if len(lines)>0 and len(lines[0])>0:
line = lines[0][:-1]
else:
r = Reason("File ["+px+"] does not contain a line of text.")
else:
r = Reason('['+px+'] is missing.')
return r,line
def envFile(env,file):
if os.environ.has_key(env):
return fncat(os.environ[env],file)
else:
print '** Environment variable ['+env+'] is not defined.'
sys.exit(1)
def envval(env):
if os.environ.has_key(env): return os.environ[env]
else: return ''
def substr(sub,base):
for i in range(len(base)):
if sub==base[i:i+len(sub)]: return 1
return 0
def safeCopy(source,target):
r = Reason()
if verbo('io'): print 'Copying ['+source+'] to ['+target+']...'
try:
# shutil.copyfile(source,target)
os.system('cp '+source+' '+target)
except (IOError,OSError):
if not os.path.exists(source):
r = Reason("Error copying ["+source+"] to ["+target+"]. File ["+source+"] does not exist.")
elif not os.path.isdir(target) and not os.path.isdir(os.path.dirname(target)):
r = Reason("Error copying ["+source+"] to ["+target+"]. Target directory does not exist.")
else:
r = Reason("Error copying ["+source+"] to ["+target+"]. You may be out of disk space.")
return r
def listStrPrt(l):
s = ''
count = 0
for ll in l:
count = count + 1
s = s + ll
if count!=len(l): s = s + ', '
return s
def rpm_installed(rpm_name):
if not fileInPath('rpm').ok():
return 0
else:
rpmTmp = rpm_name
if tail(rpmTmp,'.rpm'): rpmTmp = rpmTmp[:-4]
status,output = commands.getstatusoutput('rpm -q '+rpmTmp)
return status==0 and not contains(output,'not installed')
def yesno(message):
while 1:
try:
answer = raw_input(message+' (y or n): ')
except EOFError:
answer = 'eof'
if answer == 'y' or answer == 'yes' or answer == 'n' or answer == 'no': break
if answer == 'y' or answer == 'yes': return 1
return 0
def getFilename(message):
while 1:
filename = string.strip(raw_input(message))
if os.path.exists(fullpath(string.strip(filename))):
break
print "File ["+fullpath(filename)+"] doesn't exist. Try again..."
return fullpath(filename)
def contains(a,b,case='case sensitive'):
if case=='case sensitive': return string.count(a,b)>0
else: return string.count(string.upper(a),string.upper(b))>0
def str2file(text):
t = ''
for i in range(len(text)):
if text[i] in string.letters or text[i] in string.digits: t = t + text[i]
else: t = t + '_'
return t
def cookieDirectory(message,dire2='$PAC_ANCHOR/'+pacmanDir+'/cookies'):
dire = fullpath(dire2)
try:
if switch('ignore-cookies'): raise OSError
f = open(os.path.join(dire,str2file(message+'-'+os.getcwd())),'r')
lines = f.readlines()
f.close()
dirname = lines[0][:-1]
except (OSError,IOError):
dirname = chooseDirectory(message)
try:
f = open(os.path.join(dire,str2file(message+'-'+os.getcwd())),'w')
f.write(dirname+'\n')
f.close()
print 'Saving answer to a cookie. Use -ignore-cookies to re-choose...'
except (OSError,IOError):
print 'Warning: Failure writing cookie file to ['+os.path.join(dire,str2file(message))+']...'
return dirname
def chooseDirectory(message):
while 1:
path = string.strip(raw_input(message))
filename = os.path.dirname(path)
if path=='' or filename=='':
print path+" doesn't exist. Try again..."
elif not os.path.exists(fullpath(filename)):
print fullpath(filename)+" does not exist. Try again..."
elif not os.path.isdir(fullpath(filename)):
print fullpath(filename)+" is not a directory. Try again..."
elif not writeable(fullpath(filename)):
print fullpath(filename)+" is not writeable. Try again..."
else:
break
return os.path.join(path)
class Switch:
def __init__(self,name,options,default='on'):
self.name = name
self.options = options
self.always_on = 0
self.off = 0
self.pref = fullpath(os.path.join(pac_anchor,pacmanDir,'preferences',self.name))
self.default = default
self.useropts = []
for opt in switchItems(self.name):
if opt=='help' or not self.options.has_key(opt):
self.display()
if not self.options.has_key(opt) and not opt=='help':
print 'Unknown option -'+self.name+' '+opt+' on command line.'
sys.exit(1)
sys.exit(0)
if switch(self.name) and len(switchItems(self.name))==0 and not self.name=='debug':
self.display()
print 'No option for -'+self.name+' specified on the command line.'
sys.exit(1)
if switch(self.name) and os.path.exists(pacmanDir) and len(switchItems(self.name))>0:
try:
g = open(self.pref,'w')
for opt in switchItems(self.name): g.write(' '+opt)
g.write('\n')
g.close()
except (IOError,OSError):
abort('Error reading ['+self.pref+'].')
if switch(self.name):
self.useropts = switchItems(self.name)
else:
if os.path.exists(pacmanDir):
if os.path.exists(self.pref):
try:
f = open(self.pref,'r')
lines = f.readlines()
f.close()
if switch('def'):
sys.stdout.write('default: -'+self.name)
for opt in string.split(lines[0][:-1],' '):
opt = string.strip(opt)
if not opt=='': sys.stdout.write(' '+string.strip(opt))
sys.stdout.write('\n')
for opt in string.split(lines[0][:-1],' '):
opt = string.strip(opt)
if not opt=='': self.useropts.append(opt)
except (IOError,OSError):
abort('Error reading ['+self.pref+'].')
elif self.name=='v':
self.useropts.extend(['download-brief','cache-brief','tar-brief','up','retry'])
elif self.name=='retry':
self.useropts.extend(['10','pause-30-seconds'])
elif self.name=='ask':
self.useropts.extend(['tar-overwrite'])
elif self.name=='setups':
self.useropts.extend(['csh','sh'])
self.off = 'none' in self.useropts
self.always_on = '*' in self.useropts or 'all' in self.useropts
def save(self):
if switch(self.name) and os.path.exists(os.path.join(pac_anchor,pacmanDir)) and len(switchItems(self.name))>0:
try:
g = open(self.pref,'w')
for opt in switchItems(self.name): g.write(' '+opt)
g.write('\n')
g.close()
except (IOError,OSError):
abort('Error reading ['+self.pref+'].')
def __repr__(self): return `self.always_on`+' '+`self.useropts`
def display(self,indent=0):
print indent*' '+'Available options for -'+self.name+':'
keys = self.options.keys()
keys.sort()
for key in keys:
print indent*' '+' -'+self.name+' '+key+' '+self.options[key]
if len(self.options)>1:
print indent*' '+'Use -'+self.name+' ... for multiple options.'
def any(self):
q,val = switchpar(self.name)
return q or switch(self.name)
def __call__(self,option): return (option=='*' or self.always_on or option in self.useropts) and not self.off
def log(self,option,message,logfile='$PAC_ANCHOR/'+pacmanDir+'/logs/pacman.log'):
if os.path.isdir(os.path.dirname(fullpath(logfile))):
try:
f = open(fullpath(logfile),'a')
f.write(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())+' '+message+' -- by ['+option+'].\n')
# f.write(message+' -- by ['+option+'] at '+time.ctime(time.time())+'\n')
f.close()
except IOError,OSError:
pass
# print 'Error attempting to write to ['+fullpath(logfile)+']...'
if self(option):
print message;
return 1
else:
return 0
verbo = Switch('v', { \
'all':' All verbose messages in this list.', \
'action':' Message when Pacman takes any action defined in the lanauge.', \
'pac':' Message when searching for a package in a cache.', \
'pac-brief':' Flickering installation messages.', \
'tcp':' Message when a TCP connection is tested.', \
'shell-out':' View all shell output.', \
'shell':' Message when Pacman shell commands are executed.', \
'shell-all':' Message when any shell command is executed.', \
'registry':' Message when a registry addition is made.', \
'cu':' Message when changing usernames.', \
'download':' Downloading message and progress.', \
'download-brief':' Flickering download messages.', \
'cd':' Message when changing directories.', \
'ssh':' Message on remote ssh commands.', \
'tar':' Message for tar/zip related operations.', \
'tar-brief':' Flickering tar messages', \
'tarfiles':' Display the name of each file as it is untarred.', \
'env':' Message on environment variable operations.', \
'http':' Message for each http operation.', \
'up':' Display update related messages.', \
'gsi':' Display gsi operations.', \
'up-check':' Message when an update is checked.', \
'snap':' To view snapshot related messages.', \
'mirror':' View mirror related messages.', \
'comp':' Messages when compiling Pacman source.', \
'cache':' Cache operations.', \
'cache-brief':' Flickering cache messages.', \
'inst':' Message when putting or getting from an installation.', \
'retry':' Messages about retrying.', \
'processes':' Show running processes when using runningProcess atom.', \
'io':' Messages when doing file i/o', \
'none':' No verbose messages.', \
'users':' Message on user group or account operations.', \
'src':' Message each time a source file is opened.', \
'ptest':' Message each time a package is tested against requirements.', \
'meter':' Use ascii meters and counters.', \
'path':' Messages related to path variables.', \
'browser':' Messages when launching web browsers.', \
'restore':' Message when restoring/saving files.', \
'text':' Messages related to text line insertions and testing.' \
} )
quiet = Switch('q', { \
'down':' Suppress downloading messages.', \
'web':' Suppress updating web pages.', \
'none':' Use no quietness options.' \
} )
debug = Switch('debug',{ \
'src':' Source files', \
'status':' Package status', \
'shell':' Shell output', \
'spec':' Message each time a package specification is tested.', \
'cache':' Cache comparison', \
'setup':' Message on internal setup operations.', \
'ref':' Lazy package ref.', \
'none':' Use no debug options.', \
'os.system':' Execute shell commands with python os.system.', \
'tar-save':' Tar save.', \
'mirror-download':' Mirror download translation.', \
'tar':' Tar.', \
'ignoreShellError':'Ignore shell error codes', \
'wget':' wget feedback', \
'up':' Update.', \
'inst':' Installation operations.' \
})
browser = Switch('browser',{ \
'netscape':' Netscape', \
'mozilla':' Mozilla', \
'lynx':' Lynx (text based)', \
'w3m':' w3m (text based)', \
'galeon':' galeon' \
} )
allow = Switch('allow', { \
'any-username':' Allow any user to modify the installation (not recommended).', \
'unsupported-platforms':' Allow any os to modify the installation (not recommended).', \
'moveable-installation':' Allow Pacman installations to be copied (not recommended).', \
'non-snapshottable-downloads':' Allow downloads specified with environment variables.', \
'tar-overwrite':' Allow untarring to overwrite files.', \
'undefined-shell':' Allow shell commands containing undefined environment variables.', \
'none':' Use no allow options.', \
'no-http-cache':' Disable server side http caching.', \
'lock-override':' Override locked source caches.', \
'trust-all-caches':' Trust ALL caches automatically.', \
'bad-paths':' Allow path variables to clash.', \
'save-setup':' Allow out of date setup scripts to remain during updates (default for Pacman >= 3.19).', \
'urllib2':' Use the urllib2 python module instead of wget for downloading.', \
'any-platform':' Ignore the platform used when creating installations.', \
'old-database':' Use the old Pacman database implementation.', \
'extract-overwrite':' Allow overwriting downloaded files when using -extract-downloads.', \
'non-gnu-tar':" Try using whatever non-gnu tar program is in the installer's path.", \
'uninstall-shell-stop':" Allow a failure of an uninstall shell command to cause an error rather than be ignored.",\
'bad-tar-filenames':' Allow non-standard filename characters in untarring filenames' \
} )
setupOptions = Switch('setups', {
'csh':' C-shell setup scripts.',\
'none':' No setup scripts',\
'sh':' Bourne shell setup scripts.',\
'py':' Python setup scripts.',\
'ksh':' ksh shell setup scripts.',\
'pl':' Perl setup scripts.'
} )
upOptions = Switch('up',{
'none':' Fetch with normal update paths.', \
'fixed':' Fetch with hard-wired update paths.', \
'normal':' Fetch with normal update paths.' \
} )
httpRetry = Switch('retry',{ \
'1':' Http retry one times', \
'2':' Http retry two times', \
'3':' Http retry three times', \
'5':' Http retry five times', \
'10':' Http retry ten times', \
'20':' Http retry twenty times', \
'30':' Http retry thirty times', \
'100':' Http retry one hundred times,', \
'pause-1-second':' Pause 1 second before retrying.', \
'pause-3-seconds':' Pause 3 seconds before retrying.', \
'pause-10-seconds':' Pause 10 seconds before retrying.', \
'pause-30-seconds':' Pause 30 seconds before retrying.', \
'pause-60-seconds':' Pause 60 seconds before retrying.', \
'pause-2-minutes':' Pause 2 minutes before retrying.', \
'pause-5-minutes':' Pause 5 minutes before retrying.', \
'pause-10-minutes':' Pause 10 minutes before retrying.', \
'pause-20-minutes':' Pause 20 minutes before retrying.', \
'pause-30-minutes':' Pause 30 minutes before retrying.', \
'pause-1-hour':' Pause 1 hour before retrying.', \
'pause-5-hours':' Pause 5 hours before retrying.' \
} )
tarPause = Switch('tarpause',{ \
'1-second':' Pause 1 second before retrying.', \
'3-seconds':' Pause 3 seconds before retrying.', \
'10-seconds':' Pause 10 seconds before retrying.', \
'30-seconds':' Pause 30 seconds before retrying.', \
'60-seconds':' Pause 60 seconds before retrying.', \
'2-minutes':' Pause 2 minutes before retrying.', \
'5-minutes':' Pause 5 minutes before retrying.', \
'10-minutes':' Pause 10 minutes before retrying.', \
'20-minutes':' Pause 20 minutes before retrying.', \
'30-minutes':' Pause 30 minutes before retrying.', \
'1-hour':' Pause 1 hour before retrying.', \
'5-hours':' Pause 5 hours before retrying.' \
} )
downloadTimeout = Switch('downloadtimeout',{ \
'1-second':' Timeout after 1 second.', \
'3-seconds':' Timeout after 3 seconds.', \
'10-seconds':' Timeout after 10 seconds.', \
'30-seconds':' Timeout after 30 seconds.', \
'60-seconds':' Timeout after 60 seconds.', \
'2-minutes':' Timeout after 2 minutes.', \
'5-minutes':' Timeout after 5 minutes.', \
'10-minutes':' Timeout after 10 minutes.', \
'20-minutes':' Timeout after 20 minutes.', \
'30-minutes':' Timeout after 30 minutes.', \
'1-hour':' Timeout after 1 hour.', \
'5-hours':' Timeout after 5 hours.' \
} )
displayMode = Switch('d',{ \
'none':' All display modes off.', \
'0':' Display depth 0', \
'1':' Display depth 1', \
'2':' Display depth 2', \
'3':' Display depth 3', \
'4':' Display depth 4', \
'5':' Display depth 5', \
'6':' Display depth 6', \
'7':' Display depth 7', \
'8':' Display depth 8', \
'9':' Display depth 9', \
'all':' All displays on.', \
'description':' Display package description atoms.', \
'url':' Display package url atoms.', \
'config':' Display package configurers.', \
'version':' Display package version strings, if any.', \
'release':' Display package release strings, if any.', \
'tag':' Display package tag strings, if any.', \
'patch':' Display package patch strings, if any.', \
'option':' Display package option strings, if any.', \
'par':' Display package parents.', \
'src':' Display source code.', \
'cmp':' Display compiled environmental conditions.', \
'req':' Display requirements.', \
'up':' Display update cache.', \
'ups':' Display update source code.', \
'tar':' Display tarball contents in cmp display.', \
'file':' Display source code file name.', \
'subdir':' Display cache subdirectory containing the source file.', \
'mirror':' Display extra mirror information.', \
'snap':' Display extra snapshot information.', \
'in':' Display the cache containing the package.', \
'none':' No extra display options on.', \
'loc':' Display package starting location.', \
# Revisions display mode added by Scot Kronenfeld 2/2009
'revisions':' Display Revisions.' \
} )
def displayModeDepth():
depth = 99999
if displayMode('0'): depth = 0
elif displayMode('1'): depth = 1
elif displayMode('2'): depth = 2
elif displayMode('3'): depth = 3
elif displayMode('4'): depth = 4
elif displayMode('5'): depth = 5
elif displayMode('6'): depth = 6
elif displayMode('7'): depth = 7
elif displayMode('8'): depth = 8
elif displayMode('9'): depth = 9
return depth
def httpGetRetries():
retry = 10
if httpRetry( '1'): retry = 1
elif httpRetry( '2'): retry = 2
elif httpRetry( '3'): retry = 3
elif httpRetry( '4'): retry = 4
elif httpRetry( '5'): retry = 5
elif httpRetry( '6'): retry = 6
elif httpRetry( '7'): retry = 7
elif httpRetry( '8'): retry = 8
elif httpRetry( '10'): retry = 10
elif httpRetry( '20'): retry = 20
elif httpRetry( '30'): retry = 30
elif httpRetry('100'): retry = 100
return retry
def httpGetPause():
pause = 60
if httpRetry('pause-1-second' ): pause = 1
elif httpRetry('pause-3-seconds' ): pause = 3
elif httpRetry('pause-10-seconds' ): pause = 10
elif httpRetry('pause-30-seconds' ): pause = 30
elif httpRetry('pause-60-seconds' ): pause = 60
elif httpRetry('pause-2-minutes' ): pause = 120
elif httpRetry('pause-5-minutes' ): pause = 300
elif httpRetry('pause-10-minutes' ): pause = 600
elif httpRetry('pause-20-minutes' ): pause = 1200
elif httpRetry('pause-30-minutes' ): pause = 1800
elif httpRetry('pause-1-hour' ): pause = 3600
elif httpRetry('pause-5-hours' ): pause = 18000
return pause
def tarGetPause():
pause = 0
if tarPause('1-second' ): pause = 1
elif tarPause('3-seconds' ): pause = 3
elif tarPause('10-seconds' ): pause = 10
elif tarPause('30-seconds' ): pause = 30
elif tarPause('60-seconds' ): pause = 60
elif tarPause('2-minutes' ): pause = 120
elif tarPause('5-minutes' ): pause = 300
elif tarPause('10-minutes' ): pause = 600
elif tarPause('20-minutes' ): pause = 1200
elif tarPause('30-minutes' ): pause = 1800
elif tarPause('1-hour' ): pause = 3600
elif tarPause('5-hours' ): pause = 18000
return pause
def downloadTimeoutGet():
timeout = 1800
if downloadTimeout('1-second' ): timeout = 1
elif downloadTimeout('3-seconds' ): timeout = 3
elif downloadTimeout('10-seconds' ): timeout = 10
elif downloadTimeout('30-seconds' ): timeout = 30
elif downloadTimeout('60-seconds' ): timeout = 60
elif downloadTimeout('2-minutes' ): timeout = 120
elif downloadTimeout('5-minutes' ): timeout = 300
elif downloadTimeout('10-minutes' ): timeout = 600
elif downloadTimeout('20-minutes' ): timeout = 1200
elif downloadTimeout('30-minutes' ): timeout = 1800
elif downloadTimeout('1-hour' ): timeout = 3600
elif downloadTimeout('5-hours' ): timeout = 18000
return timeout
class Ask(Switch):
def __call__(self,option,message):
if self.always_on or option in self.useropts: return yesno(message)
else: return 1
def re(self,option,message):
return Reason(message+' has been declined.',not self(option,message))
ask = Ask('ask', { \
'cd':' Ask before cd-ing to a new directory.', \
'ssh':' Ask before executing a remote ssh command.', \
'action':' Ask before Pacman attempts any action defined in the language.', \
'shell':' Ask before executing any Pacman shell command.', \
'shell-all':' Ask before executing any shell command.', \
'shell-root':' Ask before executing a shell command as root.', \
'cu':' Ask before changing usernames.', \
'up':' Ask before updating a package.', \
'download':' Ask before any download.', \
'env':' Ask before modifying environment variables.', \
'tar':' Ask before tar operations.', \
'unzip':' Ask before unzip operatinos.', \
'tar-overwrite':' Ask permission before tar-overwriting (use with -allow tar-overwrite)', \
'mail':' Ask before emailing.', \
'http':' Ask before downloading with http.', \
'gsi':' Ask before executing each globus gsi operation', \
'none':" Don't ask permission before operations.", \
'users':' Ask before any user group or account operations.', \
'package-add':' Ask before adding a package to your installation.', \
'restore':' Ask before saving or restoring files.', \
'text-insert':' Ask before inserting or removing lines from text files.', \
'registry':' Ask before modifying the registry of symbolic cache names.', \
'retry':' Ask before download retries.', \
'path':' Ask before modifying path variables.', \
'pac':' Ask before installing or uninstalling packages.', \
'cache':' Ask before determining cache properties.' \
} )
def dots(obj):
s = `obj`
if s[-3]=='...': print s
else: print s+'...'
def rpm_replace(rpm_name):
if rpm_installed(rpm_name):
if switch('force-rpm'): return 1
elif yesno('Package ['+rpm_name+'] is already installed. Do you want to replace it?'): return 1
else: return 0
else: return 1
def deWhite(s):
ss = string.strip(s)
return ss
def deWhiten(s): return string.replace(s,' ','_')
def equivSlash(s,t):
return s==t or (len(s)>1 and s[:-1]==t) or (len(t)>1 and s==t[:-1])
def fileify(s): return s.replace('/','_').replace(':','_').replace('@','_AT_').replace(' ','_').replace('~','_').replace('.','_')
def phash(s):
import md5
MD5 = md5.md5()
MD5.update(s)
return MD5.hexdigest()
def emptyDirR(path):
e = 0
try:
e = forall(os.listdir(path),lambda f: os.path.isdir(os.path.join(path,f)) and emptyDirR(os.path.join(path,f)))
except (IOError,OSError):
e = 0
return e
def dbpath(x):
directory,base = os.path.split(x)
base2 = base
for fn in os.listdir(directory):
if fn[:len(base)]==base:
base2 = fn[:]
break
return os.path.join(directory,base2)
def gnuTarCheck():
r = Reason()
ok,tar = gnuTarFinder()
if not ok and not allow('non-gnu-tar'): r = Reason("Can't find GNU tar your path (tar/gtar/gnutar checked). GNU tar is required for Pacman.")
return r
def gnuTarCheck_old():
r = Reason()
if not fileInPath('tar').ok(): r = Reason('[tar] is not in your path.')
if r.ok() and not allow('non-gnu-tar'):
status,output = commands.getstatusoutput('tar --version')
if not status==0:
r = Reason('The [tar] in your path is not GNU tar.')
else:
if allow('non-gnu-tar'): pass
else:
if output[:13]=='tar (GNU tar)': pass
else:
r = Reason('The [tar] in your path is not GNU tar.')
return r
def gnuTarFinder():
tarOK,gtarOK,gnutarOK = 0,0,0
status,output = commands.getstatusoutput('tar --version')
outOK = 'generic tar'
if status==0 and output[:13]=='tar (GNU tar)':
tarOK = 1
outOK = output[:]
status,output = commands.getstatusoutput('gtar --version')
if status==0 and output[:13]=='tar (GNU tar)':
gtarOK = 1
outOK = output[:]
status,output = commands.getstatusoutput('gnutar --version')
if status==0 and output[:13]=='tar (GNU tar)':
gnutarOK = 1
outOK = output[:]
if tarOK: tar = 'tar'
elif gtarOK: tar = 'gtar'
elif gnutarOK: tar = 'gnutar'
else: tar = 'tar'
l = string.split(outOK,'\n')
debug.log('tar','Using ['+l[0]+'].')
return tarOK or gtarOK or gnutarOK,tar
def gnuTarName():
tarname = 'tar'
lines = []
try:
f = open(os.path.join(pac_anchor,pacmanDir,'tar'),'r')
lines = f.readlines()
f.close()
except:
lines = []
if len(lines)>0 and len(lines[0])>1:
line = string.strip(lines[0][:-1])
tarname = line
return tarname
def bounds(x):
s = string.strip(x)
if s=='one': return 1,1
elif s=='two': return 2,2
elif s=='three': return 3,3
elif s=='at most one': return 0,1
elif s=='one or more': return 1,999999
elif s=='at least one': return 1,999999
elif s=='at most two': return 0,2
elif s=='any number': return 0,999999
else: abort('Unknown local or remote installation multiplicity ['+s+'].')
class NullFile:
def write(self,x): pass
def read(self,x): pass
def close(self): pass
#
# This section makes sure that Python's anydbm module (used by shelve) does not
# use gdbm as it's default database if possible.
#
#import anydbm
#defaultdb = ''
#for _name in anydbm._names:
# if not _name=='dumbdbm' and not _name=='gdbm':
# try:
# _mod = __import__(_name)
# anydbm._defaultmod = _mod
# defaultdb = _name
# except ImportError:
# continue
# if not defaultdb=='': break
#
import pythonCheck
#use_old_database = allow('old-database') or (pythonCheck.defaultdb=='')
#use_old_database = 0
use_old_database = allow('old-database')
#if use_old_database and not os.path.exists(os.path.join(pac_anchor,pacmanDir)):
# print '** Python database modules are not installed. Using old Pacman database...'
# print '** This may cause i/o problems if your installation area is NFS mounted.'
def localPathEqual(p1,p2):
if os.path.isdir(p1) and (len(p1)==0 or not p1[-1]=='/'): t1 = p1+'/'
else: t1 = p1
if os.path.isdir(p2) and (len(p2)==0 or not p2[-1]=='/'): t2 = p2+'/'
else: t2 = p2
return t1==t2
def uname():
status,output = commands.getstatusoutput('uname -a')
u = []
if status==0:
ok = 1
u = string.split(output)
else:
ok = 0
return ok,u
def fileExistsAndContains(path,text):
q = 0
try:
f = open(path,'r')
lines = f.readlines()
f.close()
except:
lines = []
for line in lines:
if contains(line,x):
q = 1; break
return q
def askOnce(question,answer):
while answer=='':
x = raw_input(question)
if x=='y' or x=='yes':
x = 'y'; break
elif x=='n' or x=='no':
x = 'n'; break
elif x=='yall':
x = 'yall'; break
else:
print 'Choose y/n/yall. Try again...'
return x