diff --git a/secrules/FindFile.py b/secrules/FindFile.py new file mode 100644 index 0000000000000000000000000000000000000000..b8e74c2d27c25edd40a4ad53f802f797f226597c_c2VjcnVsZXMvRmluZEZpbGUucHk= --- /dev/null +++ b/secrules/FindFile.py @@ -0,0 +1,76 @@ +from vms import descrip, rmsdef, dvidef, devdef +from vms.rtl import lib +import ctypes + + +VMSLIBRTL = "/SYS$COMMON/SYSLIB/LIBRTL.EXE" +LIBRTL = ctypes.CDLL(VMSLIBRTL) +vms_find_file = getattr(LIBRTL,"LIB$FIND_FILE") +vms_find_file_end = getattr(LIBRTL,"LIB$FIND_FILE_END") +vms_trim_filespec = getattr(LIBRTL,"LIB$TRIM_FILESPEC") + +LIB_M_FIL_LONG_NAMES = 4 +NAML_C_MAXRSS = 4095 + +class FindFile(object): + def __init__(self, filespec, default_filespec=None, + flags=LIB_M_FIL_LONG_NAMES): + self.filespec = ctypes.create_string_buffer(filespec) + self.default_filespec = None if default_filespec is None else \ + descrip.bydesc(ctypes.create_string_buffer(default_filespec)) + self.resultant_filespec = \ + ctypes.create_string_buffer(NAML_C_MAXRSS + 1) + self.context = ctypes.c_uint32() + self.nullArg = ctypes.c_voidp() + self.flags = ctypes.c_uint(flags) + self.new_filespec = ctypes.create_string_buffer(NAML_C_MAXRSS + 1) + self.resultant_length = ctypes.c_uint16() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + s = vms_find_file_end(ctypes.byref(self.context)) + + def __iter__(self): + return self + + def __next__(self): + s = vms_find_file(descrip.bydesc(self.filespec), + descrip.bydesc(self.resultant_filespec), + ctypes.byref(self.context), + self.default_filespec, + self.nullArg, self.nullArg, ctypes.byref(self.flags)) + if not (s & 1): + raise StopIteration \ + if s in (rmsdef.RMS__NMF, rmsdef.RMS__FNF ) \ + else VMSError(s) + + s = vms_trim_filespec(descrip.bydesc(self.resultant_filespec), + descrip.bydesc(self.new_filespec), + self.nullArg, + ctypes.byref(self.resultant_length)) + res = self.new_filespec[:self.resultant_length.value] + # Check if the device is file oriented, lib$find_file return a file if + # a device like NLA0: is used + if (lib.getdvi(dvidef.DVI__DEVCHAR, device_name=res)[1] & + devdef.DEV_M_FOD) == 0: + raise StopIteration + return res + + def next(self): + return self.__next__() + +def file_exists(fn): + try: + with FindFile(fn) as ifn: + ifn.__next__() + return True + except (VMSError, StopIteration), e: + return False + +if __name__ == '__main__': + import sys + with FindFile(sys.argv[1]) as ifn: + for fn in ifn: + print fn