Skip to content

Commit

Permalink
Merge pull request #158 from doronz88/feature/full_ls
Browse files Browse the repository at this point in the history
shell: support all ls flags using pygnuutils
  • Loading branch information
doronz88 authored Apr 26, 2022
2 parents 03fefcc + ee46e39 commit bf186e2
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 10 deletions.
3 changes: 2 additions & 1 deletion src/rpcclient/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ pycrashreport>=0.0.8
lief
capstone
xonsh
plumbum
plumbum
pygnuutils
82 changes: 73 additions & 9 deletions src/rpcclient/rpcclient/xonshrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import os
import plistlib
import posixpath
import sys
import tempfile
import time
Expand All @@ -12,8 +13,11 @@
from uuid import UUID

import plumbum
from click.exceptions import Exit
from humanfriendly.prompts import prompt_for_choice
from pygments import highlight, formatters, lexers
from pygnuutils.cli.ls import ls as ls_cli
from pygnuutils.ls import LsStub, Ls
from xonsh.built_ins import XSH
from xonsh.cli_utils import ArgParserAlias, Annotated, Arg

Expand Down Expand Up @@ -90,6 +94,63 @@ def dir_completer(xsh, action, completer, alias, command):
return result


class RpcLsStub(LsStub):
def __init__(self, client, stdout):
self._client = client
self._stdout = stdout

@property
def sep(self):
return posixpath.sep

def join(self, path, *paths):
return posixpath.join(path, *paths)

def abspath(self, path):
return posixpath.normpath(path)

def stat(self, path, dir_fd=None, follow_symlinks=True):
if follow_symlinks:
return self._client.fs.stat(path)
return self._client.fs.lstat(path)

def readlink(self, path, dir_fd=None):
return self._client.fs.readlink(path)

def isabs(self, path):
return posixpath.isabs(path)

def dirname(self, path):
return posixpath.dirname(path)

def basename(self, path):
return posixpath.basename(path)

def getgroup(self, st_gid):
return str(st_gid)

def getuser(self, st_uid):
return str(st_uid)

def now(self):
return self._client.time.now()

def listdir(self, path='.'):
return self._client.fs.listdir(path)

def system(self):
return 'Darwin'

def getenv(self, key, default=None):
return self._client.getenv(key)

def get_tty_width(self):
return os.get_terminal_size().columns

def print(self, *objects, sep=' ', end='\n', file=sys.stdout, flush=False):
print(objects[0], end=end, file=self._stdout, flush=flush)


class XonshRc:
def __init__(self):
self.client = None # type: Union[None, rpcclient.client.Client, rpcclient.darwin.client.DarwinClient]
Expand Down Expand Up @@ -152,7 +213,7 @@ def _rpc_connect(self, hostname: str, port: Annotated[int, Arg(nargs='?', defaul
self._register_arg_parse_alias('killall', self._rpc_killall)

# -- fs
self._register_arg_parse_alias('ls', self._rpc_ls)
self._register_rpc_command('ls', self._rpc_ls)
self._register_arg_parse_alias('ln', self._rpc_ln)
self._register_arg_parse_alias('touch', self._rpc_touch)
self._register_arg_parse_alias('pwd', self._rpc_pwd)
Expand Down Expand Up @@ -284,15 +345,15 @@ def _rpc_ps(self, args, stdin, stdout, stderr):
for p in self.client.processes.list():
print(f'{p.pid:5} {p.path}', file=stdout, flush=True)

def _rpc_ls(self, path: Annotated[str, Arg(nargs='?', completer=path_completer)] = '.'):
def _rpc_ls(self, args, stdin, stdout, stderr):
""" list files """
buf = ''
for f in self.client.fs.scandir(path):
if f.is_dir():
buf += f'{f.name}/\n'
else:
buf += f'{f.name}\n'
return buf
try:
with ls_cli.make_context('ls', args) as ctx:
files = list(map(self._relative_path, ctx.params.pop('files')))
files = files if files else [self._rpc_pwd()]
Ls(RpcLsStub(self.client, stdout))(*files, **ctx.params)
except Exit:
pass

def _rpc_ln(self, src: Annotated[str, Arg(completer=path_completer)],
dst: Annotated[str, Arg(completer=path_completer)], symlink=False):
Expand Down Expand Up @@ -528,6 +589,9 @@ def _edit_remotely(self, remote):
with self._remote_file(remote) as local:
yield local

def _relative_path(self, filename):
return posixpath.join(self._rpc_pwd(), filename)

def _listdir(self, path: str) -> List[str]:
return self.client.fs.listdir(path)

Expand Down

0 comments on commit bf186e2

Please sign in to comment.