Skip to content
Snippets Groups Projects
mkbootfs.py 3.03 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/usr/bin/python2
    
    
    import os, sys, struct, optparse, StringIO, ConfigParser
    
    make_option = optparse.make_option
    
    defines = {}
    def add_var(option, opt, value, parser):
        var, val = value.split('=')
        defines[var] = val
    
    opt = optparse.OptionParser(option_list = [
            make_option('-o',
                        dest = 'output',
                        help = 'write to FILE',
                        metavar = 'FILE'),
            make_option('-d',
                        dest = 'depends',
                        help = 'write dependencies to FILE',
                        metavar = 'FILE',
                        default = None),
            make_option('-m',
                        dest = 'manifest',
                        help = 'read manifest from FILE',
                        metavar = 'FILE'),
            make_option('-D',
                        type = 'string',
                        help = 'define VAR=DATA',
                        metavar = 'VAR=DATA',
                        action = 'callback',
                        callback = add_var),
    ])
    
    (options, args) = opt.parse_args()
    
    metadata_size = 128
    depends = StringIO.StringIO()
    if options.depends:
        depends = file(options.depends, 'w')
    out = file(options.output, 'w')
    manifest = ConfigParser.SafeConfigParser()
    
    manifest.optionxform = str # avoid lowercasing
    
    manifest.read(options.manifest)
    
    depends.write('%s: \\\n' % (options.output,))
    
    files = dict([(f, manifest.get('manifest', f, vars = defines))
                  for f in manifest.options('manifest')])
    
    
    def expand(items):
        for name, hostname in items:
            if name.endswith('/**') and hostname.endswith('/**'):
                name = name[:-2]
                hostname = hostname[:-2]
                for dirpath, dirnames, filenames in os.walk(hostname):
                    for filename in filenames:
                        relpath = dirpath[len(hostname):]
    
                        if relpath != "" :
                            relpath += "/"
                        yield (name + relpath + filename,
                               hostname + relpath + filename)
    
            elif '/&/' in name and hostname.endswith('/&'):
                prefix, suffix = name.split('/&/', 1)
                yield (prefix + '/' + suffix, hostname[:-1] + suffix)
    
            else:
                yield (name, hostname)
    
    
    def unsymlink(f):
        try:
            link = os.readlink(f)
            if link.startswith('/'):
                # try to find a match
                base = os.path.dirname(f)
                while not os.path.exists(base + link):
                    base = os.path.dirname(base)
            else:
                base = os.path.dirname(f) + '/'
            return unsymlink(base + link)
        except Exception:
            return f
    
    
    files = list(expand(files.items()))
    
    files = [(x, unsymlink(y)) for (x, y) in files]
    
    pos = (len(files) + 1) * metadata_size
    
    
    for name, hostname in files:
    
        size = os.stat(hostname).st_size
        metadata = struct.pack('QQ112s', size, pos, name)
        out.write(metadata)
        pos += size
        depends.write('\t%s \\\n' % (hostname,))
    
    out.write(struct.pack('128s', ''))
    
    
    for name, hostname in files:
    
        out.write(file(hostname).read())
    
    depends.write('\n\n')
    
    out.close()
    depends.close()