Ejemplo n.º 1
0
 def realpath(fpath):
     while islink(fpath):
         rpath = readlink(fpath)
         if rpath is None:
             return fpath
         if not os.path.isabs(rpath):
             rpath = os.path.abspath(os.path.join(os.path.dirname(fpath), rpath))
         fpath = rpath
     return fpath
Ejemplo n.º 2
0
 def realpath(fpath):
     while islink(fpath):
         rpath = readlink(fpath)
         if rpath is None:
             return fpath
         if not os.path.isabs(rpath):
             rpath = os.path.abspath(
                 os.path.join(os.path.dirname(fpath), rpath))
         fpath = rpath
     return fpath
Ejemplo n.º 3
0
def is_link_to(path, target):
    def normalize(path):
        return os.path.normcase(os.path.normpath(path))
    return islink(path) and \
        normalize(realpath(path)) == normalize(realpath(target))
Ejemplo n.º 4
0
    def readlink(path):
        """ Windows readlink implementation. """
        # This wouldn't return true if the file didn't exist, as far as I know.
        if not islink(path):
            if win32_verbose:
                print("readlink(%s): not a link." % path)
            return None

        # Open the file correctly depending on the string type.
        hfile = CreateFile(path, GENERIC_READ, 0, OPEN_EXISTING,
                           FILE_FLAG_OPEN_REPARSE_POINT)

        # MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384 = (16*1024)
        buffer = DeviceIoControl(hfile, FSCTL_GET_REPARSE_POINT, None, 16384)
        CloseHandle(hfile)

        # Minimum possible length (assuming length of the target is bigger than 0)
        if not buffer or len(buffer) < 9:
            if win32_verbose:
                print("readlink(%s): no reparse buffer." % path)
            return None

        # Parse and return our result.
        # typedef struct _REPARSE_DATA_BUFFER {
        #   ULONG  ReparseTag;
        #   USHORT ReparseDataLength;
        #   USHORT Reserved;
        #   union {
        #       struct {
        #           USHORT SubstituteNameOffset;
        #           USHORT SubstituteNameLength;
        #           USHORT PrintNameOffset;
        #           USHORT PrintNameLength;
        #           ULONG Flags;
        #           WCHAR PathBuffer[1];
        #       } SymbolicLinkReparseBuffer;
        #       struct {
        #           USHORT SubstituteNameOffset;
        #           USHORT SubstituteNameLength;
        #           USHORT PrintNameOffset;
        #           USHORT PrintNameLength;
        #           WCHAR PathBuffer[1];
        #       } MountPointReparseBuffer;
        #       struct {
        #           UCHAR  DataBuffer[1];
        #       } GenericReparseBuffer;
        #   } DUMMYUNIONNAME;
        # } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;

        # Only handle SymbolicLinkReparseBuffer
        (tag, dataLength, reserver, SubstituteNameOffset, SubstituteNameLength,
         PrintNameOffset, PrintNameLength,
         Flags) = struct.unpack(SymbolicLinkReparseFormat,
                                buffer[:SymbolicLinkReparseSize])
        # print tag, dataLength, reserver, SubstituteNameOffset, SubstituteNameLength
        start = SubstituteNameOffset + SymbolicLinkReparseSize
        actualPath = buffer[start:start +
                            SubstituteNameLength].decode("utf-16")
        # This utf-16 string is null terminated
        index = actualPath.find("\0")
        if index > 0:
            actualPath = actualPath[:index]
        if actualPath.startswith("\\??\\"):  # ASCII 92, 63, 63, 92
            ret = actualPath[4:]  # strip off leading junk
        else:
            ret = actualPath
        if win32_verbose:
            print("readlink(%s->%s->%s): index(null) = %d"%\
                (path,repr(actualPath),repr(ret),index))
        return ret
Ejemplo n.º 5
0
    def readlink(path):
        """ Windows readlink implementation. """
        # This wouldn't return true if the file didn't exist, as far as I know.
        if not islink(path):
            if win32_verbose:
                print("readlink(%s): not a link."%path)
            return None

        # Open the file correctly depending on the string type.
        hfile = CreateFile(path, GENERIC_READ, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT)

        # MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384 = (16*1024)
        buffer = DeviceIoControl(hfile, FSCTL_GET_REPARSE_POINT, None, 16384)
        CloseHandle(hfile)

        # Minimum possible length (assuming length of the target is bigger than 0)
        if not buffer or len(buffer) < 9:
            if win32_verbose:
                print("readlink(%s): no reparse buffer."%path)
            return None

        # Parse and return our result.
        # typedef struct _REPARSE_DATA_BUFFER {
        #   ULONG  ReparseTag;
        #   USHORT ReparseDataLength;
        #   USHORT Reserved;
        #   union {
        #       struct {
        #           USHORT SubstituteNameOffset;
        #           USHORT SubstituteNameLength;
        #           USHORT PrintNameOffset;
        #           USHORT PrintNameLength;
        #           ULONG Flags;
        #           WCHAR PathBuffer[1];
        #       } SymbolicLinkReparseBuffer;
        #       struct {
        #           USHORT SubstituteNameOffset;
        #           USHORT SubstituteNameLength;
        #           USHORT PrintNameOffset;
        #           USHORT PrintNameLength;
        #           WCHAR PathBuffer[1];
        #       } MountPointReparseBuffer;
        #       struct {
        #           UCHAR  DataBuffer[1];
        #       } GenericReparseBuffer;
        #   } DUMMYUNIONNAME;
        # } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;

        # Only handle SymbolicLinkReparseBuffer
        (tag, dataLength, reserver, SubstituteNameOffset, SubstituteNameLength,
         PrintNameOffset, PrintNameLength,
         Flags) = struct.unpack(SymbolicLinkReparseFormat,
                                buffer[:SymbolicLinkReparseSize])
        # print tag, dataLength, reserver, SubstituteNameOffset, SubstituteNameLength
        start = SubstituteNameOffset + SymbolicLinkReparseSize
        actualPath = buffer[start : start + SubstituteNameLength].decode("utf-16")
        # This utf-16 string is null terminated
        index = actualPath.find("\0")
        if index > 0:
            actualPath = actualPath[:index]
        if actualPath.startswith("\\??\\"): # ASCII 92, 63, 63, 92
            ret = actualPath[4:]             # strip off leading junk
        else:
            ret = actualPath
        if win32_verbose:
            print("readlink(%s->%s->%s): index(null) = %d"%\
                (path,repr(actualPath),repr(ret),index))
        return ret