# some primitives for checking stream contents == code # instruction effective address register displacement immediate # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes # compare all the data in a stream (ignoring the read pointer) stream-data-equal?: # f : (address stream), s : (address string) -> EAX : boolean # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # . save registers 51/push-ECX 52/push-EDX 56/push-ESI 57/push-EDI # ESI = f 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI # EAX = f->write 8b/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy *ESI to EAX # max/EDX = f->data + f->write 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX . 2/r32/EDX 0xc/disp8 . # copy ESI+EAX+12 to EDX # currf/ESI = f->data 81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 0xc/imm32 # add to ESI # EDI = s 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 . # copy *(EBP+12) to EDI # if (f->write != s->length) return false 39/compare 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # compare *EDI and EAX 75/jump-if-not-equal $stream-data-equal?:false/disp8 # currs/EDI = s->data 81 0/subop/add 3/mod/direct 7/rm32/EDI . . . . . 4/imm32 # add to EDI # EAX = ECX = 0 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX 31/xor 3/mod/direct 1/rm32/ECX . . . 1/r32/ECX . . # clear ECX $stream-data-equal?:loop: # if (curr >= max) return true 39/compare 3/mod/direct 6/rm32/ESI . . . 2/r32/EDX . . # compare ESI with EDX 7d/jump-if-greater-or-equal $stream-data-equal?:true/disp8 # AL = *currs 8a/copy-byte 0/mod/indirect 6/rm32/ESI . . . 0/r32/AL . . # copy byte at *ESI to AL # CL = *curr 8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 1/r32/CL . . # copy byte at *EDI to CL # if (EAX != ECX) return false 39/compare 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # compare EAX and ECX 75/jump-if-not-equal $stream-data-equal?:false/disp8 # ++f 46/increment-ESI # ++curr 47/increment-EDI eb/jump $stream-data-equal?:loop/disp8 $stream-data-equal?:false: b8/copy-to-EAX 0/imm32 eb/jump $stream-data-equal?:end/disp8 $stream-data-equal?:true: b8/copy-to-EAX 1/imm32 $stream-data-equal?:end: # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 5a/pop-to-EDX 59/pop-to-ECX # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return test-stream-data-equal: # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # clear-stream(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call
# Tested with ranger 1.7.0 through ranger 1.7.*
#
# This plugin creates a FIFO in /tmp/ranger-ipc.<PID> to which any
# other program may write. Lines written to this file are evaluated by
# ranger as the ranger :commands.
#
# Example:
# $ echo tab_new ~/images > /tmp/ranger-ipc.1234
import ranger.api
old_hook_init = ranger.api.hook_init
def hook_init(fm):
try:
# Create a FIFO.
import os
IPC_FIFO = "/tmp/ranger-ipc." + str(os.getpid())
os.mkfifo(IPC_FIFO)
# Start the reader thread.
try:
import thread
except ImportError:
import _thread as thread
def ipc_reader(filepath):
while True:
with open(filepath, 'r') as fifo:
line = fifo.read()
fm.execute_console(line.strip())
thread.start_new_thread(ipc_reader, (IPC_FIFO,))
# Remove the FIFO on ranger exit.
def ipc_cleanup(filepath):
try:
os.unlink(filepath)
except IOError:
pass
import atexit
atexit.register(ipc_cleanup, IPC_FIFO)
except IOError:
# IPC support disabled
pass
finally:
old_hook_init(fm)
ranger.api.hook_init = hook_init