createrepo patch to optionally use /usr/bin/file to detect rpms

Jay Soffian <[email protected]>
Newsgroups gmane.linux.rpm.metadata
Message-ID <[email protected]>
I have a repository of RPMs whose names do not contain an .rpm  
extension, but that I still need to index with createrepo.

I put together a quick patch that allows genpkgmetadata to optionally  
call out to /usr/bin/file to examine any files it encounters that  
don't have the normal .rpm extension (files which do have .rpm are  
assumed to be rpms and are not passed to /usr/bin/file).

This behavior is optional and is enabled with -m or --magic.

Requires a version of /usr/bin/file that supports -f (files-from), -i  
(mime output) and -b (brief mode). Lightly tested on RHEL AS 3.

I seem to recall that Python has a module which provides similar  
functionality to /usr/bin/file but it's not jumping out at me right  
now and this patch took all of 15 minutes.

j.

_______________________________________________
Rpm-metadata mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/rpm-metadata
genpkgmetadata-magic.patch (application/octet-stream, 5.5 KB)
--- /Users/jay/cvsroot/generate/genpkgmetadata.py	2006-08-11 16:01:38.000000000 -0400
+++ genpkgmetadata.py	2006-09-11 07:55:46.000000000 -0400
@@ -58,6 +58,8 @@
      -c, --cachedir <dir> = specify which dir to use for the checksum cache
      -C, --checkts = don't generate repo metadata, if their ctimes are newer
                      than the rpm ctimes.
+     -m, --magic = use /usr/bin/file to detect RPMs that may not have a normal
+                   file extension (.rpm).
      -h, --help = show this help
      -V, --version = output version
      -p, --pretty = output xml files in pretty format.
@@ -76,9 +78,30 @@
         """Return all files in path matching ext, store them in filelist,
         recurse dirs. Returns a list object"""
 
+        magictmp = self.cmds['magictmp']
+
+        def magic_visitor(filelist, dirname, names):
+            paths = map(lambda n:os.path.join(dirname, n), names)
+            f = open(magictmp, "w")
+            try:
+                f.write("\n".join(paths) + "\n")
+                f.close()
+                p = os.popen("/usr/bin/file -bif %s" % magictmp)
+                mimetypes = map(string.strip, p.readlines())
+                p.close()
+            finally:
+                os.unlink(magictmp)
+            assert len(names) == len(paths) == len(mimetypes)
+            for fn, mimetype in zip(names, mimetypes):
+                if mimetype == "application/x-rpm":
+                    relativepath = dirname.replace(startdir, "", 1)
+                    relativepath = relativepath.lstrip("/")
+                    filelist.append(os.path.join(relativepath,fn))
+
         extlen = len(ext)
 
         def extension_visitor(filelist, dirname, names):
+            others = []
             for fn in names:
                 if os.path.isdir(fn):
                     continue
@@ -86,6 +109,10 @@
                     relativepath = dirname.replace(startdir, "", 1)
                     relativepath = relativepath.lstrip("/")
                     filelist.append(os.path.join(relativepath,fn))
+                else:
+                    others.append(fn)
+            if self.cmds['magic']:
+                magic_visitor(filelist, dirname, others)
 
         filelist = []
         startdir = os.path.join(basepath, directory) + '/'
@@ -289,9 +316,31 @@
 
     def getFileList(self, basepath, directory, ext):
 
+        magictmp = self.cmds['magictmp']
+
+        def magic_visitor(arg, dirname, names):
+            paths = map(lambda n:os.path.join(dirname, n), names)
+            f = open(magictmp, "w")
+            try:
+                f.write("\n".join(paths) + "\n")
+                f.close()
+                p = os.popen("/usr/bin/file -bif %s" % magictmp)
+                mimetypes = map(string.strip, p.readlines())
+                p.close()
+            finally:
+                os.unlink(magictmp)
+            assert len(names) == len(paths) == len(mimetypes)
+            for fn, mimetype in zip(names, mimetypes):
+                if mimetype == "application/x-rpm":
+                    reldir = os.path.basename(dirname)
+                    if reldir == os.path.basename(directory):
+                        reldir = ""
+                    arg.append(os.path.join(reldir,fn))
+
         extlen = len(ext)
 
         def extension_visitor(arg, dirname, names):
+            others = []
             for fn in names:
                 if os.path.isdir(fn):
                     continue
@@ -300,7 +349,11 @@
                     if reldir == os.path.basename(directory):
                         reldir = ""
                     arg.append(os.path.join(reldir,fn))
-
+                else:
+                    others.append(fn)
+            if self.cmds['magic']:
+                magic_visitor(arg, dirname, others)
+                  
         rpmlist = []
         startdir = os.path.join(basepath, directory)
         os.path.walk(startdir, extension_visitor, rpmlist)
@@ -376,16 +429,17 @@
     cmds['checkts'] = False
     cmds['mdtimestamp'] = 0
     cmds['split'] = False
+    cmds['magic'] = False
     cmds['outputdir'] = ""
     cmds['file-pattern-match'] = ['.*bin\/.*', '^\/etc\/.*', '^\/usr\/lib\/sendmail$']
     cmds['dir-pattern-match'] = ['.*bin\/.*', '^\/etc\/.*']
 
     try:
-        gopts, argsleft = getopt.getopt(args, 'phqVvng:s:x:u:c:o:C', ['help', 'exclude=',
+        gopts, argsleft = getopt.getopt(args, 'phqVvnmg:s:x:u:c:o:C', ['help', 'exclude=',
                                                                   'quiet', 'verbose', 'cachedir=', 'basedir=',
                                                                   'baseurl=', 'groupfile=', 'checksum=',
                                                                   'version', 'pretty', 'split', 'outputdir=',
-                                                                  'noepoch', 'checkts'])
+                                                                  'noepoch', 'checkts', 'magic'])
     except getopt.error, e:
         errorprint(_('Options Error: %s.') % e)
         usage()
@@ -451,6 +505,9 @@
                 cmds['outputdir'] = a
             elif arg in ['-n', '--noepoch']:
                 cmds['noepoch'] = True
+            elif arg in ['-m', '--magic']:
+                cmds['magic'] = True
+
                     
     except ValueError, e:
         errorprint(_('Options Error: %s') % e)
@@ -499,6 +556,7 @@
     cmds['tempdir'] = '.repodata'
     cmds['finaldir'] = 'repodata'
     cmds['olddir'] = '.olddata'
+    cmds['magictmp'] = "/tmp/genpkgmetadata-tmp.%s" % os.getpid()
 
     # Fixup first directory
     directories[0] = directory
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.