Fuser
Description
fuser is a tool that will try and find out which program is using/locking a file.
Author
License
Not Specified
Script
/* fuser.cmd - finds user(s) of an open file D C Saville September 2003 dave@deezee.org Have you ever tried to do something to a file only to get a message saying "File in use by another programme"? Fine but *which* programme. fuser will try and find out. Sometimes it can't, in which case you will get no output, but often it will find who or what has the file open. */ Parse Upper Arg file '¬' rest If file = "" Then Do Say "Usage: fuser <file name>" Exit End file = Translate(file, "\", "/") /* just in case the file has forward slashes */ psfiles_q = RxQueue( "create" ) pstat_q = RxQueue( "create" ) OldQueue = RxQueue( "set", psfiles_q ) "@psfiles | RXQUEUE" psfiles_q Do Queued() Parse Pull pid Hdl SFN refs flags mode size hvpb attr file_name If Pos(file, file_name) > 0 Then Do Say "pid Hdl SFN refs flags mode size hvpb attr name" Say pid Hdl SFN refs flags mode size hvpb attr file_name FILE_NORMAL = X2B("0000") FILE_READONLY = X2B("0001") FILE_HIDDEN = X2B("0002") FILE_SYSTEM = X2B("0004") FILE_DIRECTORY = X2B("0010") FILE_ARCHIVED = X2B("0020") File_attr = "File attr: " attr = X2B(attr) If BitAnd(attr, FILE_READONLY) = FILE_READONLY Then File_attr = File_attr||"Read_Only " If BitAnd(attr, FILE_HIDDEN) = FILE_HIDDEN Then File_attr = File_attr||"Hidden " If BitAnd(attr, FILE_SYSTEM) = FILE_SYSTEM Then File_attr = File_attr||"System " If BitAnd(attr, FILE_DIRECTORY) = FILE_DIRECTORY Then File_attr = File_attr||"Directory " If BitAnd(attr, FILE_ARCHIVED) = FILE_ARCHIVED Then File_attr = File_attr||"Archived " Say file_attr OPEN_FLAGS_NOINHERIT = X2B("00000080") OPEN_FLAGS_NO_LOCALITY = X2B("00000000") OPEN_FLAGS_NO_SEQUENTIAL = X2B("00000100") OPEN_FLAGS_NO_RANDOM = X2B("00000200") OPEN_FLAGS_NO_RANDOMSEQUENTIAL = X2B("00000200") OPEN_FLAGS_NOCACHE = X2B("00001000") OPEN_FLAGS_FAIL_ON_ERROR = X2B("00002000") OPEN_FLAGS_WRITE_THROUGH = X2B("00004000") OPEN_FLAGS_DASD = X2B("00008000") OPEN_FLAGS_NONSPOOLED = X2B("00040000") OPEN_FLAGS_PROTECTED_HANDLE = X2B("40000000") OPEN_SHARE_DENYLEGACY = X2B("10000000") OPEN_SHARE_DENYREADWRITE = X2B("00000010") OPEN_SHARE_DENYWRITE = X2B("00000020") OPEN_SHARE_DENYREAD = X2B("00000030") OPEN_SHARE_DENYNONE = X2B("00000040") OPEN_ACCESS_READONLY = X2B("00000000") OPEN_ACCESS_WRITEONLY = X2B("00000001") OPEN_ACCESS_READWRITE = X2B("00000002") file_mode = "File mode: " mode = X2B(mode) If BitAnd(mode , OPEN_FLAGS_NOINHERIT) = OPEN_FLAGS_NOINHERIT Then file_mode = file_mode||"private. " Else file_mode = file_mode||"inherited from DosExecPgm. " file_mode = file_mode||"Share: " If BitAnd(mode , OPEN_SHARE_DENYNONE) = OPEN_SHARE_DENYNONE Then file_mode = file_mode||"deny none. " If BitAnd(mode , OPEN_SHARE_DENYREAD) = OPEN_SHARE_DENYREAD Then file_mode = file_mode||"deny read. " Else Do If BitAnd(mode , OPEN_SHARE_DENYWRITE) = OPEN_SHARE_DENYWRITE Then file_mode = file_mode||"deny write. " If BitAnd(mode , OPEN_SHARE_DENYREADWRITE) = OPEN_SHARE_DENYREADWRITE Then file_mode = file_mode||"deny read & write " End file_mode = file_mode||"Opened for: " If BitAnd(mode , OPEN_ACCESS_READWRITE) = OPEN_ACCESS_READWRITE Then file_mode = file_mode||"read & write. " If BitAnd(mode , OPEN_ACCESS_WRITEONLY) = OPEN_ACCESS_WRITEONLY Then file_mode = file_mode||"write only. " If BitAnd(mode , BitOr(OPEN_ACCESS_WRITEONLY, OPEN_ACCESS_READWRITE)) = OPEN_ACCESS_READONLY Then file_mode = file_mode||"read only. " If BitAnd(mode , OPEN_FLAGS_WRITE_THROUGH) = OPEN_FLAGS_WRITE_THROUGH Then file_mode = file_mode||"synchronous. " Say file_mode If pid <> 0 Then Do Call RxQueue "set", pstat_q "@pstat /P:"||pid||" | RXQUEUE" pstat_q Do Queued() Parse Pull stuff If Translate(SubStr(stuff, 1, 4)) = Translate(pid) Then Do p1 = Pos(":", stuff) p2 = Pos(" ", SubStr(stuff, p1 + 1)) /*prog_name = Strip(SubStr(stuff, p1 - 1, p2 + 1))*/ Say "Program: "||word(stuff, 4) End End Call RxQueue "set", psfiles_q /* restore pfiles queue */ End Else Say "Program: System, DLL or Zombie" Say End End CALL RxQueue "Delete", pstat_q /* don't need our queue anymore */ CALL RxQueue "Delete", psfiles_q /* don't need our queue anymore */ CALL RxQueue "Set", OldQueue /* restore old queue */