예제 #1
0
 def __init__(self, remote, create=False):
     self.closed = False
     self._busy = self.conn = None
     self.sock = self.p = self.pout = self.pin = None
     try:
         is_reverse = environ.get(b'BUP_SERVER_REVERSE')
         if is_reverse:
             assert(not remote)
             remote = b'%s:' % is_reverse
         (self.protocol, self.host, self.port, self.dir) = parse_remote(remote)
         # The b'None' here matches python2's behavior of b'%s' % None == 'None',
         # python3 will (as of version 3.7.5) do the same for str ('%s' % None),
         # but crashes instead when doing b'%s' % None.
         cachehost = b'None' if self.host is None else self.host
         cachedir = b'None' if self.dir is None else self.dir
         self.cachedir = git.repo(b'index-cache/%s'
                                  % re.sub(br'[^@\w]',
                                           b'_',
                                           b'%s:%s' % (cachehost, cachedir)))
         if is_reverse:
             self.pout = os.fdopen(3, 'rb')
             self.pin = os.fdopen(4, 'wb')
             self.conn = Conn(self.pout, self.pin)
         else:
             if self.protocol in (b'ssh', b'file'):
                 try:
                     # FIXME: ssh and file shouldn't use the same module
                     self.p = ssh.connect(self.host, self.port, b'server')
                     self.pout = self.p.stdout
                     self.pin = self.p.stdin
                     self.conn = Conn(self.pout, self.pin)
                 except OSError as e:
                     reraise(ClientError('connect: %s' % e))
             elif self.protocol == b'bup':
                 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                 self.sock.connect((self.host,
                                    1982 if self.port is None else int(self.port)))
                 self.sockw = self.sock.makefile('wb')
                 self.conn = DemuxConn(self.sock.fileno(), self.sockw)
         self._available_commands = self._get_available_commands()
         self._require_command(b'init-dir')
         self._require_command(b'set-dir')
         if self.dir:
             self.dir = re.sub(br'[\r\n]', ' ', self.dir)
             if create:
                 self.conn.write(b'init-dir %s\n' % self.dir)
             else:
                 self.conn.write(b'set-dir %s\n' % self.dir)
             self.check_ok()
         self.sync_indexes()
     except BaseException as ex:
         with pending_raise(ex):
             self.close()
예제 #2
0
파일: client.py 프로젝트: jmberg/bup
    def __init__(self, remote, create=False):
        self._busy = self.conn = None
        self.sock = self.p = self.pout = self.pin = None
        (self.protocol, self.host, self.port, self.dir) = parse_remote(remote)
        if self.protocol == b'reverse':
            self.pout = os.fdopen(3, 'rb')
            self.pin = os.fdopen(4, 'wb')
            self.conn = Conn(self.pout, self.pin)
        if self.protocol in (b'ssh', b'file'):
            try:
                # FIXME: ssh and file shouldn't use the same module
                self.p = ssh.connect(self.host, self.port, b'server')
                self.pout = self.p.stdout
                self.pin = self.p.stdin
                self.conn = Conn(self.pout, self.pin)
            except OSError as e:
                reraise(ClientError('connect: %s' % e))
        elif self.protocol == b'bup':
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect((self.host,
                               1982 if self.port is None else int(self.port)))
            self.sockw = self.sock.makefile('wb')
            self.conn = DemuxConn(self.sock.fileno(), self.sockw)
        self._available_commands = self._get_available_commands()
        self._require_command(b'init-dir')
        self._require_command(b'set-dir')
        if self.dir:
            self.dir = re.sub(br'[\r\n]', ' ', self.dir)
            if create:
                self.conn.write(b'init-dir %s\n' % self.dir)
            else:
                self.conn.write(b'set-dir %s\n' % self.dir)
            self.check_ok()

        # Set up the index-cache directory, prefer using the repo-id
        # if the remote repo has one (that can be accessed)
        repo_id = self.config(b'bup.repo-id')
        if repo_id is not None:
            self.cachedir = path.cachedir(repo_id)
        else:
            # The b'None' here matches python2's behavior of b'%s' % None == 'None',
            # python3 will (as of version 3.7.5) do the same for str ('%s' % None),
            # but crashes instead when doing b'%s' % None.
            cachehost = b'None' if self.host is None else self.host
            cachedir = b'None' if self.dir is None else self.dir
            self.cachedir = path.cachedir(re.sub(br'[^@\w]',
                                                 b'_',
                                                 b'%s:%s' % (cachehost, cachedir)))

        self.sync_indexes()
예제 #3
0
def main(argv):
    o = options.Options(optspec)
    opt, flags, extra = o.parse_bytes(argv[1:])

    if extra:
        o.fatal('no arguments expected')

    debug2('bup server: reading from stdin.\n')

    # FIXME: this protocol is totally lame and not at all future-proof.
    # (Especially since we abort completely as soon as *anything* bad happens)
    sys.stdout.flush()
    conn = Conn(byte_stream(sys.stdin), byte_stream(sys.stdout))
    lr = linereader(conn)
    for _line in lr:
        line = _line.strip()
        if not line:
            continue
        debug1('bup server: command: %r\n' % line)
        words = line.split(b' ', 1)
        cmd = words[0]
        rest = len(words)>1 and words[1] or b''
        if cmd == b'quit':
            break
        else:
            cmd = commands.get(cmd)
            if cmd:
                cmd(conn, rest)
            else:
                raise Exception('unknown server command: %r\n' % line)

    debug1('bup server: done\n')
예제 #4
0
파일: server.py 프로젝트: jmberg/bup
def main(argv):
    o = options.Options(optspec)
    opt, flags, extra = o.parse_bytes(argv[1:])

    if extra:
        o.fatal('no arguments expected')

    debug2('bup server: reading from stdin.\n')

    class ServerRepo(LocalRepo):
        def __init__(self, repo_dir):
            if opt.force_repo:
                repo_dir = None
            LocalRepo.__init__(self, repo_dir)

    def _restrict(server, commands):
        for fn in dir(server):
            if getattr(fn, 'bup_server_command', False):
                if not fn in commands:
                    del cls.fn

    modes = ['unrestricted', 'append', 'read-append', 'read']
    if opt.mode is not None and opt.mode not in modes:
        o.fatal("server: invalid mode")

    BupProtocolServer(Conn(byte_stream(sys.stdin), byte_stream(sys.stdout)),
                      ServerRepo, mode=opt.mode).handle()
예제 #5
0
파일: client.py 프로젝트: lwwhsh/bup
 def __init__(self, remote, create=False):
     self._busy = self.conn = None
     self.sock = self.p = self.pout = self.pin = None
     is_reverse = os.environ.get('BUP_SERVER_REVERSE')
     if is_reverse:
         assert (not remote)
         remote = '%s:' % is_reverse
     (self.protocol, self.host, self.port, self.dir) = parse_remote(remote)
     self.cachedir = git.repo('index-cache/%s' %
                              re.sub(r'[^@\w]', '_', "%s:%s" %
                                     (self.host, self.dir)))
     if is_reverse:
         self.pout = os.fdopen(3, 'rb')
         self.pin = os.fdopen(4, 'wb')
         self.conn = Conn(self.pout, self.pin)
     else:
         if self.protocol in ('ssh', 'file'):
             try:
                 # FIXME: ssh and file shouldn't use the same module
                 self.p = ssh.connect(self.host, self.port, 'server')
                 self.pout = self.p.stdout
                 self.pin = self.p.stdin
                 self.conn = Conn(self.pout, self.pin)
             except OSError as e:
                 raise ClientError, 'connect: %s' % e, sys.exc_info()[2]
         elif self.protocol == 'bup':
             self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             self.sock.connect((self.host, atoi(self.port) or 1982))
             self.sockw = self.sock.makefile('wb')
             self.conn = DemuxConn(self.sock.fileno(), self.sockw)
     self._available_commands = self._get_available_commands()
     self._require_command('init-dir')
     self._require_command('set-dir')
     if self.dir:
         self.dir = re.sub(r'[\r\n]', ' ', self.dir)
         if create:
             self.conn.write('init-dir %s\n' % self.dir)
         else:
             self.conn.write('set-dir %s\n' % self.dir)
         self.check_ok()
     self.sync_indexes()
예제 #6
0
    'set-dir': set_dir,
    'list-indexes': list_indexes,
    'send-index': send_index,
    'receive-objects-v2': receive_objects_v2,
    'read-ref': read_ref,
    'update-ref': update_ref,
    'join': join,
    'cat': join,  # apocryphal alias
    'cat-batch' : cat_batch,
    'refs': refs,
    'rev-list': rev_list
}

# FIXME: this protocol is totally lame and not at all future-proof.
# (Especially since we abort completely as soon as *anything* bad happens)
conn = Conn(sys.stdin, sys.stdout)
lr = linereader(conn)
for _line in lr:
    line = _line.strip()
    if not line:
        continue
    debug1('bup server: command: %r\n' % line)
    words = line.split(' ', 1)
    cmd = words[0]
    rest = len(words)>1 and words[1] or ''
    if cmd == 'quit':
        break
    else:
        cmd = commands.get(cmd)
        if cmd:
            cmd(conn, rest)
예제 #7
0
파일: server-cmd.py 프로젝트: zzmjohn/bup
    b'send-index': send_index,
    b'receive-objects-v2': receive_objects_v2,
    b'read-ref': read_ref,
    b'update-ref': update_ref,
    b'join': join,
    b'cat': join,  # apocryphal alias
    b'cat-batch': cat_batch,
    b'refs': refs,
    b'rev-list': rev_list,
    b'resolve': resolve
}

# FIXME: this protocol is totally lame and not at all future-proof.
# (Especially since we abort completely as soon as *anything* bad happens)
sys.stdout.flush()
conn = Conn(byte_stream(sys.stdin), byte_stream(sys.stdout))
lr = linereader(conn)
for _line in lr:
    line = _line.strip()
    if not line:
        continue
    debug1('bup server: command: %r\n' % line)
    words = line.split(b' ', 1)
    cmd = words[0]
    rest = len(words) > 1 and words[1] or b''
    if cmd == b'quit':
        break
    else:
        cmd = commands.get(cmd)
        if cmd:
            cmd(conn, rest)
예제 #8
0
        if getattr(fn, 'bup_server_command', False):
            if not fn in commands:
                del cls.fn


# always allow these - even if set-dir may actually be
# a no-op (if --force-repo is given)
permitted = set(
    [b'quit', b'help', b'set-dir', b'list-indexes', b'send-index', b'config'])

read_cmds = set(
    [b'read-ref', b'join', b'cat-batch', b'refs', b'rev-list', b'resolve'])
append_cmds = set(
    [b'receive-objects-v2', b'read-ref', b'update-ref', b'init-dir'])

if opt.mode is None or opt.mode == 'unrestricted':
    permitted = None  # all commands permitted
elif opt.mode == 'append':
    permitted.update(append_cmds)
elif opt.mode == 'read-append':
    permitted.update(read_cmds)
    permitted.update(append_cmds)
elif opt.mode == 'read':
    permitted.update(read_cmds)
else:
    o.fatal("server: invalid mode")

BupProtocolServer(Conn(byte_stream(sys.stdin), byte_stream(sys.stdout)),
                  ServerRepo,
                  permitted_commands=permitted).handle()