aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'portage_with_autodep/pym/_emerge/EventsLogger.py')
-rw-r--r--portage_with_autodep/pym/_emerge/EventsLogger.py180
1 files changed, 180 insertions, 0 deletions
diff --git a/portage_with_autodep/pym/_emerge/EventsLogger.py b/portage_with_autodep/pym/_emerge/EventsLogger.py
new file mode 100644
index 0000000..68b3c67
--- /dev/null
+++ b/portage_with_autodep/pym/_emerge/EventsLogger.py
@@ -0,0 +1,180 @@
+# Distributed under the terms of the GNU General Public License v2
+
+import io
+import sys
+import stat
+import socket
+import select
+import tempfile
+
+import threading
+
+from portage import os
+
+class EventsLogger(threading.Thread):
+ def default_filter(eventname, filename, stage):
+ return True
+
+ def __init__(self, socket_dir="/tmp/", filter_proc=default_filter):
+ threading.Thread.__init__(self) # init the Thread
+
+ self.alive=False
+
+ self.main_thread=threading.currentThread()
+
+ self.socket_dir=socket_dir
+ self.filter_proc=filter_proc
+
+ self.socket_name=None
+ self.socket_logger=None
+
+ self.events={}
+
+ try:
+ socket_dir_name = tempfile.mkdtemp(dir=self.socket_dir,
+ prefix="log_socket_")
+
+ socket_name = os.path.join(socket_dir_name, 'socket')
+
+ except OSError as e:
+ return
+
+ self.socket_name=socket_name
+
+ #print(self.socket_name)
+
+ try:
+ socket_logger=socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
+ socket_logger.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+ socket_logger.bind(self.socket_name)
+ socket_logger.listen(64)
+
+ except socket.error as e:
+ return
+
+ self.socket_logger=socket_logger
+
+ try:
+ # Allow connecting to socket for anyone
+ os.chmod(socket_dir_name,
+ stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|
+ stat.S_IROTH|stat.S_IWOTH|stat.S_IXOTH)
+ os.chmod(socket_name,
+ stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|
+ stat.S_IROTH|stat.S_IWOTH|stat.S_IXOTH)
+ except OSError as e:
+ return
+
+ def run(self):
+ """ Starts the log server """
+
+ self.alive=True
+ self.listen_thread=threading.currentThread()
+ clients={}
+
+ epoll=select.epoll()
+ epoll.register(self.socket_logger.fileno(), select.EPOLLIN)
+
+ while self.alive:
+ try:
+ sock_events = epoll.poll(3)
+
+ for fileno, sock_event in sock_events:
+ if fileno == self.socket_logger.fileno():
+ ret = self.socket_logger.accept()
+ if ret is None:
+ pass
+ else:
+ (client,addr)=ret
+ epoll.register(client.fileno(), select.EPOLLIN)
+ clients[client.fileno()]=client
+ elif sock_event & select.EPOLLIN:
+ s=clients[fileno]
+ record=s.recv(8192)
+
+ if not record: # if connection was closed
+ epoll.unregister(fileno)
+ clients[fileno].close()
+ del clients[fileno]
+ continue
+
+ #import pdb; pdb.set_trace()
+ try:
+ message=record.decode("utf8").split("\0")
+ except UnicodeDecodeError:
+ print("Bad message %s" % record)
+ continue
+
+ # continue
+
+ #print(message)
+
+ try:
+ if message[4]=="ASKING":
+ if self.filter_proc(message[1],message[2],message[3]):
+ s.sendall(b"ALLOW\0")
+ else:
+ # TODO: log through portage infrastructure
+ #print("Blocking an access to %s" % message[2])
+ s.sendall(b"DENY\0")
+ else:
+ eventname,filename,stage,result=message[1:5]
+
+ if not stage in self.events:
+ self.events[stage]=[{},{}]
+
+ hashofsucesses=self.events[stage][0]
+ hashoffailures=self.events[stage][1]
+
+ if result=="DENIED":
+ print("Blocking an access to %s" % filename)
+
+ if result=="OK":
+ if not filename in hashofsucesses:
+ hashofsucesses[filename]=[False,False]
+
+ readed_or_writed=hashofsucesses[filename]
+
+ if eventname=="read":
+ readed_or_writed[0]=True
+ elif eventname=="write":
+ readed_or_writed[1]=True
+
+ elif result[0:3]=="ERR" or result=="DENIED":
+ if not filename in hashoffailures:
+ hashoffailures[filename]=[False,False]
+ notfound_or_blocked=hashoffailures[filename]
+
+ if result=="ERR/2":
+ notfound_or_blocked[0]=True
+ elif result=="DENIED":
+ notfound_or_blocked[1]=True
+
+ else:
+ print("Error in logger module<->analyser protocol")
+
+ except IndexError:
+ print("IndexError while parsing %s" % record)
+ except IOError as e:
+ if e.errno!=4: # handling "Interrupted system call" errors
+ raise
+
+ # if main thread doesnt exists then exit
+ if not self.main_thread.is_alive():
+ break
+ epoll.unregister(self.socket_logger.fileno())
+ epoll.close()
+ self.socket_logger.close()
+
+ def stop(self):
+ """ Stops the log server. Returns all events """
+
+ self.alive=False
+
+ # Block the main thread until listener exists
+ self.listen_thread.join()
+
+ # We assume portage clears tmp folder, so no deleting a socket file
+ # We assume that no new socket data will arrive after this moment
+ return self.events