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()
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()
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')
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()
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()
'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)
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)
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()