def _receive(self, type): """ Read data, check version number, extract headers, and returns a tuple (data descriptor, header) Raises QueryFailed on error """ cs = common.recvcs(self.sock) try: version = ord(cs.read(1)) except TypeError: # empty answer, assume the server crashed self.ui.warn(_('inotify-client: received empty answer from inotify ' 'server')) raise QueryFailed('server crashed') if version != common.version: self.ui.warn(_('(inotify: received response from incompatible ' 'server version %d)\n') % version) raise QueryFailed('incompatible server version') readtype = cs.read(4) if readtype != type: self.ui.warn(_('(inotify: received \'%s\' response when expecting' ' \'%s\')\n') % (readtype, type)) raise QueryFailed('wrong response type') hdrfmt = common.resphdrfmts[type] hdrsize = common.resphdrsizes[type] try: resphdr = struct.unpack(hdrfmt, cs.read(hdrsize)) except struct.error: raise QueryFailed('unable to retrieve query response headers') return cs, resphdr
def query(ui, repo, names, match, list_ignored, list_clean, list_unknown=True): sock = socket.socket(socket.AF_UNIX) sockpath = repo.join('inotify.sock') sock.connect(sockpath) def genquery(): for n in names or []: yield n states = 'almrx!' if list_ignored: raise ValueError('this is insanity') if list_clean: states += 'n' if list_unknown: states += '?' yield states req = '\0'.join(genquery()) sock.sendall(chr(common.version)) sock.sendall(req) sock.shutdown(socket.SHUT_WR) cs = common.recvcs(sock) version = ord(cs.read(1)) if version != common.version: ui.warn(_('(inotify: received response from incompatible server ' 'version %d)\n') % version) return None try: resphdr = struct.unpack(common.resphdrfmt, cs.read(common.resphdrsize)) except struct.error: return None def readnames(nbytes): if nbytes: names = cs.read(nbytes) if names: return filter(match, names.split('\0')) return [] return map(readnames, resphdr)
def accept_connection(self): sock, addr = self.sock.accept() cs = common.recvcs(sock) version = ord(cs.read(1)) if version != common.version: self.ui.warn( _('received query from incompatible client ' 'version %d\n') % version) try: # try to send back our version to the client # this way, the client too is informed of the mismatch sock.sendall(chr(common.version)) except: pass return type = cs.read(4) if type == 'STAT': results = self.answer_stat_query(cs) elif type == 'DBUG': results = self.answer_dbug_query() else: self.ui.warn(_('unrecognized query type: %s\n') % type) return try: try: v = chr(common.version) sock.sendall( v + type + struct.pack(common.resphdrfmts[type], *map(len, results))) sock.sendall(''.join(results)) finally: sock.shutdown(socket.SHUT_WR) except socket.error, err: if err.args[0] != errno.EPIPE: raise
def accept_connection(self): sock, addr = self.sock.accept() cs = common.recvcs(sock) version = ord(cs.read(1)) if version != common.version: self.ui.warn(_('received query from incompatible client ' 'version %d\n') % version) try: # try to send back our version to the client # this way, the client too is informed of the mismatch sock.sendall(chr(common.version)) except: pass return type = cs.read(4) if type == 'STAT': results = self.answer_stat_query(cs) elif type == 'DBUG': results = self.answer_dbug_query() else: self.ui.warn(_('unrecognized query type: %s\n') % type) return try: try: v = chr(common.version) sock.sendall(v + type + struct.pack(common.resphdrfmts[type], *map(len, results))) sock.sendall(''.join(results)) finally: sock.shutdown(socket.SHUT_WR) except socket.error, err: if err[0] != errno.EPIPE: raise
def handle_event(self, fd, event): sock, addr = self.sock.accept() cs = common.recvcs(sock) version = ord(cs.read(1)) sock.sendall(chr(common.version)) if version != common.version: self.ui.warn(_('received query from incompatible client ' 'version %d\n') % version) return names = cs.read().split('\0') states = names.pop() self.ui.note(_('answering query for %r\n') % states) if self.watcher.timeout: # We got a query while a rescan is pending. Make sure we # rescan before responding, or we could give back a wrong # answer. self.watcher.handle_timeout() if not names: def genresult(states, tree): for fn, state in self.watcher.walk(states, tree): yield fn else: def genresult(states, tree): for fn in names: l = self.watcher.lookup(fn, tree) try: if l in states: yield fn except TypeError: for f, s in self.watcher.walk(states, l, fn): yield f results = ['\0'.join(r) for r in [ genresult('l', self.watcher.statustrees['l']), genresult('m', self.watcher.statustrees['m']), genresult('a', self.watcher.statustrees['a']), genresult('r', self.watcher.statustrees['r']), genresult('!', self.watcher.statustrees['!']), '?' in states and genresult('?', self.watcher.statustrees['?']) or [], [], 'c' in states and genresult('n', self.watcher.tree) or [], ]] try: try: sock.sendall(struct.pack(common.resphdrfmt, *map(len, results))) sock.sendall(''.join(results)) finally: sock.shutdown(socket.SHUT_WR) except socket.error, err: if err[0] != errno.EPIPE: raise