Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
Importing options.py, ssh.py, and LICENSE from the bup project.
  • Loading branch information
apenwarr committed May 1, 2010
0 parents commit 2f3c86e
Show file tree
Hide file tree
Showing 6 changed files with 636 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.pyc
*~
481 changes: 481 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env python
import ssh, options
118 changes: 118 additions & 0 deletions options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import sys, textwrap, getopt, re

class OptDict:
def __init__(self):
self._opts = {}

def __setitem__(self, k, v):
self._opts[k] = v

def __getitem__(self, k):
return self._opts[k]

def __getattr__(self, k):
return self[k]


class Options:
def __init__(self, exe, optspec, optfunc=getopt.gnu_getopt):
self.exe = exe
self.optspec = optspec
self.optfunc = optfunc
self._aliases = {}
self._shortopts = 'h?'
self._longopts = ['help']
self._hasparms = {}
self._usagestr = self._gen_usage()

def _gen_usage(self):
out = []
lines = self.optspec.strip().split('\n')
lines.reverse()
first_syn = True
while lines:
l = lines.pop()
if l == '--': break
out.append('%s: %s\n' % (first_syn and 'usage' or ' or', l))
first_syn = False
out.append('\n')
while lines:
l = lines.pop()
if l.startswith(' '):
out.append('\n%s\n' % l.lstrip())
elif l:
(flags, extra) = l.split(' ', 1)
extra = extra.strip()
if flags.endswith('='):
flags = flags[:-1]
has_parm = 1
else:
has_parm = 0
flagl = flags.split(',')
flagl_nice = []
for f in flagl:
f_nice = re.sub(r'\W', '_', f)
self._aliases[f] = flagl[0]
self._aliases[f_nice] = flagl[0]
self._hasparms[f] = has_parm
if len(f) == 1:
self._shortopts += f + (has_parm and ':' or '')
flagl_nice.append('-' + f)
else:
assert(not f.startswith('no-')) # supported implicitly
self._longopts.append(f + (has_parm and '=' or ''))
self._longopts.append('no-' + f)
flagl_nice.append('--' + f)
flags_nice = ', '.join(flagl_nice)
if has_parm:
flags_nice += ' ...'
prefix = ' %-20s ' % flags_nice
argtext = '\n'.join(textwrap.wrap(extra, width=70,
initial_indent=prefix,
subsequent_indent=' '*28))
out.append(argtext + '\n')
else:
out.append('\n')
return ''.join(out).rstrip() + '\n'

def usage(self):
sys.stderr.write(self._usagestr)
sys.exit(97)

def fatal(self, s):
sys.stderr.write('error: %s\n' % s)
return self.usage()

def parse(self, args):
try:
(flags,extra) = self.optfunc(args, self._shortopts, self._longopts)
except getopt.GetoptError, e:
self.fatal(e)

opt = OptDict()
for f in self._aliases.values():
opt[f] = None
for (k,v) in flags:
while k.startswith('-'):
k = k[1:]
if k in ['h', '?', 'help']:
self.usage()
if k.startswith('no-'):
k = self._aliases[k[3:]]
opt[k] = None
else:
k = self._aliases[k]
if not self._hasparms[k]:
assert(v == '')
opt[k] = (opt._opts.get(k) or 0) + 1
else:
try:
vv = int(v)
if str(vv) == v:
v = vv
except ValueError:
pass
opt[k] = v
for (f1,f2) in self._aliases.items():
opt[f1] = opt[f2]
return (opt,flags,extra)
32 changes: 32 additions & 0 deletions ssh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import os, re, subprocess

def connect(rhost, subcmd):
assert(not re.search(r'[^\w-]', subcmd))
main_exe = sys.argv[0]
nicedir = os.path.split(os.path.abspath(main_exe))[0]
nicedir = re.sub(r':', "_", nicedir)
if rhost == '-':
rhost = None
if not rhost:
argv = ['sshuttle', subcmd]
else:
# WARNING: shell quoting security holes are possible here, so we
# have to be super careful. We have to use 'sh -c' because
# csh-derived shells can't handle PATH= notation. We can't
# set PATH in advance, because ssh probably replaces it. We
# can't exec *safely* using argv, because *both* ssh and 'sh -c'
# allow shellquoting. So we end up having to double-shellquote
# stuff here.
escapedir = re.sub(r'([^\w/])', r'\\\\\\\1', nicedir)
cmd = r"""
sh -c PATH=%s:'$PATH sshuttle %s'
""" % (escapedir, subcmd)
argv = ['ssh', rhost, '--', cmd.strip()]
def setup():
# runs in the child process
if not rhost:
os.environ['PATH'] = ':'.join([nicedir,
os.environ.get('PATH', '')])
os.setsid()
return subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
preexec_fn=setup)
1 change: 1 addition & 0 deletions sshuttle

0 comments on commit 2f3c86e

Please sign in to comment.