Represent files inside packages as PkgFile objects.
git-svn-id: svn+ssh://rpmlint.zarb.org/home/projects/rpmlint/svn/trunk@1543 9bc8b190-ac0f-0410-8968-dc7d1f502856
This commit is contained in:
parent
ee8d1ae115
commit
68731ec1c8
|
@ -218,7 +218,7 @@ class BinariesCheck(AbstractCheck.AbstractCheck):
|
||||||
multi_pkg = 0
|
multi_pkg = 0
|
||||||
|
|
||||||
for f in files:
|
for f in files:
|
||||||
if usr_lib_regex.search(f) and not usr_lib_exception_regex.search(f) and not stat.S_ISDIR(files[f][0]):
|
if usr_lib_regex.search(f) and not usr_lib_exception_regex.search(f) and not stat.S_ISDIR(files[f].mode):
|
||||||
has_usr_lib_file = f
|
has_usr_lib_file = f
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -269,8 +269,7 @@ class BinariesCheck(AbstractCheck.AbstractCheck):
|
||||||
(directory, base) = dir_base(i[0])
|
(directory, base) = dir_base(i[0])
|
||||||
try:
|
try:
|
||||||
symlink = directory + bin_info.soname
|
symlink = directory + bin_info.soname
|
||||||
(perm, owner, group, link, size, md5, mtime, rdev, lang, inode, deps) = files[symlink]
|
if files[symlink].linkto not in (i[0], base, ''):
|
||||||
if link != i[0] and link != base and link != '':
|
|
||||||
printError(pkg, 'invalid-ldconfig-symlink', i[0], link)
|
printError(pkg, 'invalid-ldconfig-symlink', i[0], link)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
printError(pkg, 'no-ldconfig-symlink', i[0])
|
printError(pkg, 'no-ldconfig-symlink', i[0])
|
||||||
|
|
|
@ -42,8 +42,8 @@ class DocFilesCheck(AbstractCheck.AbstractCheck):
|
||||||
doc_files = pkg.docFiles()
|
doc_files = pkg.docFiles()
|
||||||
|
|
||||||
reqs = {}
|
reqs = {}
|
||||||
for fname, fattrs in files.items():
|
for fname, pkgfile in files.items():
|
||||||
tmp = fattrs[10].split()
|
tmp = pkgfile.deps.split()
|
||||||
tmp = _stripVersionedDeps(tmp)
|
tmp = _stripVersionedDeps(tmp)
|
||||||
reqs[fname] = tmp
|
reqs[fname] = tmp
|
||||||
|
|
||||||
|
|
|
@ -309,14 +309,14 @@ class FilesCheck(AbstractCheck.AbstractCheck):
|
||||||
# Unique (rdev, inode) combinations
|
# Unique (rdev, inode) combinations
|
||||||
hardlinks = {}
|
hardlinks = {}
|
||||||
|
|
||||||
for f, fattrs in files.items():
|
for f, pkgfile in files.items():
|
||||||
mode = fattrs[0]
|
mode = pkgfile.mode
|
||||||
user = fattrs[1]
|
user = pkgfile.user
|
||||||
group = fattrs[2]
|
group = pkgfile.group
|
||||||
link = fattrs[3]
|
link = pkgfile.linkto
|
||||||
size = fattrs[4]
|
size = pkgfile.size
|
||||||
rdev = fattrs[7]
|
rdev = pkgfile.rdev
|
||||||
inode = fattrs[9]
|
inode = pkgfile.inode
|
||||||
is_doc = f in doc_files
|
is_doc = f in doc_files
|
||||||
nonexec_file = 0
|
nonexec_file = 0
|
||||||
|
|
||||||
|
@ -587,7 +587,7 @@ class FilesCheck(AbstractCheck.AbstractCheck):
|
||||||
# relative link
|
# relative link
|
||||||
else:
|
else:
|
||||||
if not is_so:
|
if not is_so:
|
||||||
extractedfile = '%s%s/%s' % (pkg.dirName(), os.path.dirname(f), link)
|
extractedfile = os.path.join(os.path.dirname(pkgfile.path), link)
|
||||||
extractedfile = os.path.normpath(extractedfile)
|
extractedfile = os.path.normpath(extractedfile)
|
||||||
pkgfile = '%s/%s' % (os.path.dirname(f), link)
|
pkgfile = '%s/%s' % (os.path.dirname(f), link)
|
||||||
pkgfile = os.path.normpath(pkgfile)
|
pkgfile = os.path.normpath(pkgfile)
|
||||||
|
@ -637,7 +637,7 @@ class FilesCheck(AbstractCheck.AbstractCheck):
|
||||||
|
|
||||||
# check text file
|
# check text file
|
||||||
if stat.S_ISREG(mode):
|
if stat.S_ISREG(mode):
|
||||||
path = pkg.dirName() + '/' + f
|
path = pkgfile.path
|
||||||
if os.access(path, os.R_OK):
|
if os.access(path, os.R_OK):
|
||||||
if istextfile(path, pkg):
|
if istextfile(path, pkg):
|
||||||
fobj = open(path, 'r')
|
fobj = open(path, 'r')
|
||||||
|
|
|
@ -148,12 +148,12 @@ class I18NCheck(AbstractCheck.AbstractCheck):
|
||||||
subdir = None
|
subdir = None
|
||||||
|
|
||||||
if f.endswith('.mo') or subdir:
|
if f.endswith('.mo') or subdir:
|
||||||
if pkg.fileLang(f) == '' and not webapp:
|
if pkg.files()[f].lang == '' and not webapp:
|
||||||
printWarning(pkg, 'file-not-in-%lang', f)
|
printWarning(pkg, 'file-not-in-%lang', f)
|
||||||
|
|
||||||
main_dir, main_lang = ("", "")
|
main_dir, main_lang = ("", "")
|
||||||
for f in files:
|
for f in files:
|
||||||
lang = pkg.fileLang(f)
|
lang = pkg.files()[f].lang
|
||||||
if main_lang and lang == "" and is_prefix(main_dir + '/', f):
|
if main_lang and lang == "" and is_prefix(main_dir + '/', f):
|
||||||
printError(pkg, 'subfile-not-in-%lang', f)
|
printError(pkg, 'subfile-not-in-%lang', f)
|
||||||
if main_lang != lang:
|
if main_lang != lang:
|
||||||
|
|
|
@ -48,11 +48,11 @@ class InitScriptCheck(AbstractCheck.AbstractCheck):
|
||||||
return
|
return
|
||||||
|
|
||||||
initscript_list = []
|
initscript_list = []
|
||||||
for fname, fattrs in pkg.files().items():
|
for fname, pkgfile in pkg.files().items():
|
||||||
if rc_regex.search(fname):
|
if rc_regex.search(fname):
|
||||||
basename = os.path.basename(fname)
|
basename = os.path.basename(fname)
|
||||||
initscript_list.append(basename)
|
initscript_list.append(basename)
|
||||||
if fattrs[0] & 0500 != 0500:
|
if pkgfile.mode & 0500 != 0500:
|
||||||
printError(pkg, 'init-script-non-executable', fname)
|
printError(pkg, 'init-script-non-executable', fname)
|
||||||
|
|
||||||
if dot_in_name_regex.match(basename):
|
if dot_in_name_regex.match(basename):
|
||||||
|
@ -83,7 +83,7 @@ class InitScriptCheck(AbstractCheck.AbstractCheck):
|
||||||
# check common error in file content
|
# check common error in file content
|
||||||
content = None
|
content = None
|
||||||
try:
|
try:
|
||||||
content = Pkg.readlines(pkg.dirName() + '/' + fname)
|
content = Pkg.readlines(pkgfile.path)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
printWarning(pkg, 'read-error', e)
|
printWarning(pkg, 'read-error', e)
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -170,10 +170,10 @@ class MenuCheck(AbstractCheck.AbstractCheck):
|
||||||
files = pkg.files()
|
files = pkg.files()
|
||||||
menus = []
|
menus = []
|
||||||
|
|
||||||
for fname, fattrs in files.items():
|
for fname, pkgfile in files.items():
|
||||||
# Check menu files
|
# Check menu files
|
||||||
res = menu_file_regex.search(fname)
|
res = menu_file_regex.search(fname)
|
||||||
mode = fattrs[0]
|
mode = pkgfile.mode
|
||||||
if res:
|
if res:
|
||||||
basename = res.group(1)
|
basename = res.group(1)
|
||||||
if not stat.S_ISREG(mode):
|
if not stat.S_ISREG(mode):
|
||||||
|
|
94
Pkg.py
94
Pkg.py
|
@ -197,8 +197,9 @@ class Pkg:
|
||||||
self.current_linenum = None
|
self.current_linenum = None
|
||||||
self._config_files = None
|
self._config_files = None
|
||||||
self._doc_files = None
|
self._doc_files = None
|
||||||
|
self._noreplace_files = None
|
||||||
self._ghost_files = None
|
self._ghost_files = None
|
||||||
self._missing_ok_files = None
|
self._missingok_files = None
|
||||||
self._files = None
|
self._files = None
|
||||||
self._requires = None
|
self._requires = None
|
||||||
self._req_names = -1
|
self._req_names = -1
|
||||||
|
@ -321,6 +322,7 @@ class Pkg:
|
||||||
def files(self):
|
def files(self):
|
||||||
if self._files is not None:
|
if self._files is not None:
|
||||||
return self._files
|
return self._files
|
||||||
|
|
||||||
self._gatherFilesInfo()
|
self._gatherFilesInfo()
|
||||||
return self._files
|
return self._files
|
||||||
|
|
||||||
|
@ -328,45 +330,49 @@ class Pkg:
|
||||||
def configFiles(self):
|
def configFiles(self):
|
||||||
if self._config_files is not None:
|
if self._config_files is not None:
|
||||||
return self._config_files
|
return self._config_files
|
||||||
self._gatherFilesInfo()
|
|
||||||
|
self._config_files = [x.name for x in self.files().values()
|
||||||
|
if x.is_config]
|
||||||
return self._config_files
|
return self._config_files
|
||||||
|
|
||||||
# return the list of noreplace files
|
# return the list of noreplace files
|
||||||
def noreplaceFiles(self):
|
def noreplaceFiles(self):
|
||||||
if self._noreplace_files is not None:
|
if self._noreplace_files is not None:
|
||||||
return self._noreplace_files
|
return self._noreplace_files
|
||||||
self._gatherFilesInfo()
|
|
||||||
|
self._noreplace_files = [x.name for x in self.files().values()
|
||||||
|
if x.is_noreplace]
|
||||||
return self._noreplace_files
|
return self._noreplace_files
|
||||||
|
|
||||||
# return the list of documentation files
|
# return the list of documentation files
|
||||||
def docFiles(self):
|
def docFiles(self):
|
||||||
if self._doc_files is not None:
|
if self._doc_files is not None:
|
||||||
return self._doc_files
|
return self._doc_files
|
||||||
self._gatherFilesInfo()
|
|
||||||
|
self._doc_files = [x.name for x in self.files().values() if x.is_doc]
|
||||||
return self._doc_files
|
return self._doc_files
|
||||||
|
|
||||||
# return the list of ghost files
|
# return the list of ghost files
|
||||||
def ghostFiles(self):
|
def ghostFiles(self):
|
||||||
if self._ghost_files is not None:
|
if self._ghost_files is not None:
|
||||||
return self._ghost_files
|
return self._ghost_files
|
||||||
self._gatherFilesInfo()
|
|
||||||
|
self._ghost_files = [x.name for x in self.files().values()
|
||||||
|
if x.is_ghost]
|
||||||
return self._ghost_files
|
return self._ghost_files
|
||||||
|
|
||||||
def missingOkFiles(self):
|
def missingOkFiles(self):
|
||||||
if self._missing_ok_files is not None:
|
if self._missingok_files is not None:
|
||||||
return self._missing_ok_files
|
return self._missingok_files
|
||||||
self._gatherFilesInfo()
|
|
||||||
return self._missing_ok_files
|
self._missingok_files = [x.name for x in self.files().values()
|
||||||
|
if x.is_missingok]
|
||||||
|
return self._missingok_files
|
||||||
|
|
||||||
# extract information about the files
|
# extract information about the files
|
||||||
def _gatherFilesInfo(self):
|
def _gatherFilesInfo(self):
|
||||||
global v304
|
global v304
|
||||||
|
|
||||||
self._config_files = []
|
|
||||||
self._doc_files = []
|
|
||||||
self._noreplace_files = []
|
|
||||||
self._ghost_files = []
|
|
||||||
self._missing_ok_files = []
|
|
||||||
self._files = {}
|
self._files = {}
|
||||||
flags = self.header[rpm.RPMTAG_FILEFLAGS]
|
flags = self.header[rpm.RPMTAG_FILEFLAGS]
|
||||||
modes = self.header[rpm.RPMTAG_FILEMODES]
|
modes = self.header[rpm.RPMTAG_FILEMODES]
|
||||||
|
@ -407,24 +413,21 @@ class Pkg:
|
||||||
|
|
||||||
if files:
|
if files:
|
||||||
for idx in range(0, len(files)):
|
for idx in range(0, len(files)):
|
||||||
if flags[idx] & RPMFILE_CONFIG:
|
pkgfile = PkgFile(files[idx])
|
||||||
self._config_files.append(files[idx])
|
pkgfile.path = os.path.join(self.dirName(), pkgfile.name)
|
||||||
if flags[idx] & RPMFILE_DOC:
|
pkgfile.flags = flags[idx]
|
||||||
self._doc_files.append(files[idx])
|
pkgfile.mode = modes[idx]
|
||||||
if flags[idx] & RPMFILE_NOREPLACE:
|
pkgfile.user = users[idx]
|
||||||
self._noreplace_files.append(files[idx])
|
pkgfile.group = groups[idx]
|
||||||
if flags[idx] & RPMFILE_GHOST:
|
pkgfile.linkto = links[idx]
|
||||||
self._ghost_files.append(files[idx])
|
pkgfile.size = sizes[idx]
|
||||||
if flags[idx] & RPMFILE_MISSINGOK:
|
pkgfile.md5 = md5s[idx]
|
||||||
self._missing_ok_files.append(files[idx])
|
pkgfile.mtime = mtimes[idx]
|
||||||
self._files[files[idx]] = (modes[idx], users[idx],
|
pkgfile.rdev = rdevs[idx]
|
||||||
groups[idx], links[idx],
|
pkgfile.inode = inodes[idx]
|
||||||
sizes[idx], md5s[idx],
|
pkgfile.deps = deps[idx]
|
||||||
mtimes[idx], rdevs[idx],
|
pkgfile.lang = langs[idx]
|
||||||
langs[idx], inodes[idx], deps[idx])
|
self._files[pkgfile.name] = pkgfile
|
||||||
|
|
||||||
def fileLang(self, f):
|
|
||||||
return self.files()[f][8]
|
|
||||||
|
|
||||||
# API to access dependency information
|
# API to access dependency information
|
||||||
def obsoletes(self):
|
def obsoletes(self):
|
||||||
|
@ -592,6 +595,33 @@ class FakePkg:
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Class for files in packages
|
||||||
|
class PkgFile(object):
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
# Real path to the file (taking extract dir into account)
|
||||||
|
self.path = name
|
||||||
|
self.flags = 0
|
||||||
|
self.mode = 0
|
||||||
|
self.user = None
|
||||||
|
self.group = None
|
||||||
|
self.linkto = ''
|
||||||
|
self.size = None
|
||||||
|
self.md5 = None
|
||||||
|
self.mtime = 0
|
||||||
|
self.rdev = ''
|
||||||
|
self.inode = 0
|
||||||
|
self.deps = ''
|
||||||
|
self.lang = ''
|
||||||
|
|
||||||
|
is_config = property(lambda self: self.flags & RPMFILE_CONFIG)
|
||||||
|
is_doc = property(lambda self: self.flags & RPMFILE_DOC)
|
||||||
|
is_noreplace = property(lambda self: self.flags & RPMFILE_NOREPLACE)
|
||||||
|
is_ghost = property(lambda self: self.flags & RPMFILE_GHOST)
|
||||||
|
is_missingok = property(lambda self: self.flags & RPMFILE_MISSINGOK)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
for p in sys.argv[1:]:
|
for p in sys.argv[1:]:
|
||||||
pkg = Pkg(sys.argv[1], tempfile.gettempdir())
|
pkg = Pkg(sys.argv[1], tempfile.gettempdir())
|
||||||
|
|
|
@ -34,7 +34,7 @@ class SourceCheck(AbstractCheck.AbstractCheck):
|
||||||
|
|
||||||
# process file list
|
# process file list
|
||||||
spec_file = None
|
spec_file = None
|
||||||
for fname, fattrs in pkg.files().items():
|
for fname, pkgfile in pkg.files().items():
|
||||||
if fname.endswith('.spec'):
|
if fname.endswith('.spec'):
|
||||||
if spec_file:
|
if spec_file:
|
||||||
printError(pkg, 'multiple-specfiles', spec_file, fname)
|
printError(pkg, 'multiple-specfiles', spec_file, fname)
|
||||||
|
@ -47,7 +47,7 @@ class SourceCheck(AbstractCheck.AbstractCheck):
|
||||||
else:
|
else:
|
||||||
if not fname.endswith('gz'):
|
if not fname.endswith('gz'):
|
||||||
printWarning(pkg, 'source-or-patch-not-gzipped', fname)
|
printWarning(pkg, 'source-or-patch-not-gzipped', fname)
|
||||||
perm = fattrs[0] & 07777
|
perm = pkgfile.mode & 07777
|
||||||
if perm not in valid_src_perms:
|
if perm not in valid_src_perms:
|
||||||
printWarning(pkg, 'strange-permission', fname, oct(perm))
|
printWarning(pkg, 'strange-permission', fname, oct(perm))
|
||||||
|
|
||||||
|
|
|
@ -154,9 +154,9 @@ class SpecCheck(AbstractCheck.AbstractCheck):
|
||||||
wrong_spec = False
|
wrong_spec = False
|
||||||
|
|
||||||
# lookup spec file
|
# lookup spec file
|
||||||
for fname in pkg.files():
|
for fname, pkgfile in pkg.files().items():
|
||||||
if fname.endswith('.spec'):
|
if fname.endswith('.spec'):
|
||||||
self._spec_file = pkg.dirName() + "/" + fname
|
self._spec_file = pkgfile.path
|
||||||
if fname == pkg.name + ".spec":
|
if fname == pkg.name + ".spec":
|
||||||
wrong_spec = False
|
wrong_spec = False
|
||||||
break
|
break
|
||||||
|
|
|
@ -31,8 +31,8 @@ class ZipCheck(AbstractCheck.AbstractCheck):
|
||||||
AbstractCheck.AbstractCheck.__init__(self, "ZipCheck")
|
AbstractCheck.AbstractCheck.__init__(self, "ZipCheck")
|
||||||
|
|
||||||
def check(self, pkg):
|
def check(self, pkg):
|
||||||
for fname in pkg.files():
|
for fname, pkgfile in pkg.files().items():
|
||||||
path = pkg.dirName() + fname
|
path = pkgfile.path
|
||||||
if zip_regex.search(fname) and os.path.exists(path) and \
|
if zip_regex.search(fname) and os.path.exists(path) and \
|
||||||
stat.S_ISREG(os.lstat(path)[stat.ST_MODE]) and \
|
stat.S_ISREG(os.lstat(path)[stat.ST_MODE]) and \
|
||||||
zipfile.is_zipfile(path):
|
zipfile.is_zipfile(path):
|
||||||
|
|
18
rpmdiff
18
rpmdiff
|
@ -37,16 +37,16 @@ TAGS = [ (rpm.RPMTAG_NAME, 'NAME'),
|
||||||
(rpm.RPMTAG_POSTUN, 'POSTUN'),
|
(rpm.RPMTAG_POSTUN, 'POSTUN'),
|
||||||
]
|
]
|
||||||
|
|
||||||
FILEIDX = [ ('S', 4),
|
FILEIDX = [ ('S', 'size'),
|
||||||
('M', 0),
|
('M', 'mode'),
|
||||||
('5', 5),
|
('5', 'md5'),
|
||||||
('D', None),
|
('D', None),
|
||||||
('L', 3),
|
('L', 'linkto'),
|
||||||
('U', 1),
|
('U', 'user'),
|
||||||
('G', 2),
|
('G', 'group'),
|
||||||
(None, None),
|
(None, None),
|
||||||
]
|
]
|
||||||
FILEIDX_T = ('T', 6)
|
FILEIDX_T = ('T', 'mtime')
|
||||||
|
|
||||||
DEPFORMAT = '%-11s%s %s %s %s'
|
DEPFORMAT = '%-11s%s %s %s %s'
|
||||||
FORMAT = '%-11s%s'
|
FORMAT = '%-11s%s'
|
||||||
|
@ -176,7 +176,9 @@ def main():
|
||||||
format = ''
|
format = ''
|
||||||
for idx in range(0, len(FILEIDX)):
|
for idx in range(0, len(FILEIDX)):
|
||||||
entry = FILEIDX[idx]
|
entry = FILEIDX[idx]
|
||||||
if entry[1] is not None and old_file[entry[1]] != new_file[entry[1]]:
|
prop = entry[1]
|
||||||
|
if entry[1] is not None and \
|
||||||
|
getattr(old_file, prop) != getattr(new_file, prop):
|
||||||
format = format + entry[0]
|
format = format + entry[0]
|
||||||
diff = 1
|
diff = 1
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue