def FileFromFilesystem(path, pathId, possibleMatch = None, inodeInfo = False,
        assumeRoot=False, statBuf=None, sha1FailOk=False):
    if statBuf:
        s = statBuf
    else:
        s = os.lstat(path)

    global userCache, groupCache, _havePrelink

    if assumeRoot:
        owner = 'root'
        group = 'root'
    elif isinstance(s.st_uid, basestring):
        # Already stringified -- some capsule code will fabricate a stat result
        # from e.g. a RPM header
        owner = s.st_uid
        group = s.st_gid
    else:
        # + is not a valid char in user/group names; if the uid is not mapped
        # to a user, prepend it with + and store it as a string
        try:
            owner = userCache.lookupId('/', s.st_uid)
        except KeyError:
            owner = '+%d' % s.st_uid

        try:
            group = groupCache.lookupId('/', s.st_gid)
        except __HOLE__:
            group = '+%d' % s.st_gid

    needsSha1 = 0
    inode = InodeStream(s.st_mode & 07777, s.st_mtime, owner, group)

    if (stat.S_ISREG(s.st_mode)):
        f = RegularFile(pathId)
        needsSha1 = 1
    elif (stat.S_ISLNK(s.st_mode)):
        f = SymbolicLink(pathId)
        if hasattr(s, 'linkto'):
            f.target.set(s.linkto)
        else:
            f.target.set(os.readlink(path))
    elif (stat.S_ISDIR(s.st_mode)):
        f = Directory(pathId)
    elif (stat.S_ISSOCK(s.st_mode)):
        f = Socket(pathId)
    elif (stat.S_ISFIFO(s.st_mode)):
        f = NamedPipe(pathId)
    elif (stat.S_ISBLK(s.st_mode)):
        f = BlockDevice(pathId)
        f.devt.major.set(s.st_rdev >> 8)
        f.devt.minor.set(s.st_rdev & 0xff)
    elif (stat.S_ISCHR(s.st_mode)):
        f = CharacterDevice(pathId)
        f.devt.major.set(s.st_rdev >> 8)
        f.devt.minor.set(s.st_rdev & 0xff)
    else:
        raise FilesError("unsupported file type for %s" % path)

    f.inode = inode
    f.flags = FlagsStream(0)

    # assume we have a match if the FileMode and object type match
    if possibleMatch and (possibleMatch.__class__ == f.__class__) \
                     and f.inode == possibleMatch.inode \
                     and f.inode.mtime() == possibleMatch.inode.mtime() \
                     and (not s.st_size or
                          (possibleMatch.hasContents and
                           s.st_size == possibleMatch.contents.size())):
        f.flags.set(possibleMatch.flags())
        return possibleMatch
    elif (possibleMatch and (isinstance(f, RegularFile) and
                             isinstance(possibleMatch, RegularFile))
                        and (f.inode.isExecutable())
                        and f.inode.mtime() == possibleMatch.inode.mtime()
                        and f.inode.owner == possibleMatch.inode.owner
                        and f.inode.group == possibleMatch.inode.group
                        and f.inode.perms == possibleMatch.inode.perms):
        # executable RegularFiles match even if there sizes are different
        # as long as everything else is the same; this is to stop size
        # changes from prelink from changing fileids
        return possibleMatch

    if needsSha1:
        f.contents = RegularFileStream()

        undoPrelink = False
        if _havePrelink != False and f.inode.isExecutable():
            try:
                from conary.lib import elf
                if elf.prelinked(path):
                    undoPrelink = True
            except:
                pass
        if undoPrelink and _havePrelink is None:
            _havePrelink = bool(os.access(PRELINK_CMD[0], os.X_OK))
        if undoPrelink and _havePrelink:
            prelink = subprocess.Popen(
                    PRELINK_CMD + ('-uo', '-', path),
                    stdout = subprocess.PIPE,
                    close_fds = True,
                    shell = False)
            d = digestlib.sha1()
            content = prelink.stdout.read()
            size = 0
            while content:
                d.update(content)
                size += len(content)
                content = prelink.stdout.read()

            prelink.wait()
            f.contents.size.set(size)
            sha1 = d.digest()
        else:
            try:
                sha1 = sha1helper.sha1FileBin(path)
            except OSError:
                if sha1FailOk:
                    sha1 = sha1helper.sha1Empty
                else:
                    raise
            f.contents.size.set(s.st_size)

        f.contents.sha1.set(sha1)

    if inodeInfo:
        return (f, s.st_nlink, (s.st_rdev, s.st_ino))

    return f
dataset/ETHPy150Open sassoftware/conary/conary/files.py/FileFromFilesystem