aboutsummaryrefslogtreecommitdiffstats
path: root/alfred/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'alfred/server.py')
-rw-r--r--alfred/server.py67
1 files changed, 54 insertions, 13 deletions
diff --git a/alfred/server.py b/alfred/server.py
index cfb4c69..a369b88 100644
--- a/alfred/server.py
+++ b/alfred/server.py
@@ -15,6 +15,7 @@ Commands (owner only) - use !server or !srv:
!server conns - TCP connection summary
!server who - logged-in users
!server logs <service> [n] - last n lines of service log (default 10)
+ !server scan [path] - run clamscan on path (default: mail)
"""
import os
@@ -28,18 +29,30 @@ if _alfred_dir not in _sys.path:
import helpstrings as h
SERVICES = [
- "nginx", "postfix", "dovecot", "ngircd", "soju",
+ "nginx", "postfix", "dovecot", "ngircd", "soju", "websocat",
"opendkim", "fcgiwrap", "alfred", "dcron", "0x0",
+ "xandikos", "wg-quick.wg0",
]
LOG_PATHS = {
- "nginx": ["/var/log/nginx/error.log", "/var/log/nginx/access.log"],
- "postfix": ["/var/log/mail.log", "/var/log/messages"],
- "dovecot": ["/var/log/dovecot.log", "/var/log/messages"],
- "ngircd": ["/var/log/ngircd.log", "/var/log/messages"],
- "soju": ["/var/log/soju.log", "/var/log/messages"],
- "alfred": ["/var/log/alfred/sopel.log", "/var/log/alfred/daemon.log"],
- "herald": ["/var/log/herald/sopel.log", "/var/log/herald/daemon.log"],
+ "nginx": ["/var/log/nginx/error.log", "/var/log/nginx/access.log"],
+ "postfix": ["/var/log/mail.log", "/var/log/messages"],
+ "dovecot": ["/var/log/dovecot.log", "/var/log/messages"],
+ "ngircd": ["/var/log/ngircd.log", "/var/log/messages"],
+ "soju": ["/var/log/soju.log"],
+ "websocat": ["/var/log/websocat/daemon.log"],
+ "0x0": ["/var/log/0x0/daemon.log", "/var/log/0x0/prune.log"],
+ "xandikos": ["/var/log/xandikos/daemon.log"],
+ "alfred": ["/var/log/alfred/sopel.log", "/var/log/alfred/daemon.log"],
+ "herald": ["/var/log/herald/sopel.log", "/var/log/herald/daemon.log"],
+ "bikabot": ["/var/log/bikabot/sopel.log", "/var/log/bikabot/daemon.log"],
+ "daft": ["/var/log/daft/sopel.log", "/var/log/daft/daemon.log"],
+ "daffy": ["/var/log/daffy/sopel.log", "/var/log/daffy/daemon.log"],
+ "contessa": ["/var/log/contessa/sopel.log", "/var/log/contessa/daemon.log"],
+ "osterman": ["/var/log/osterman/sopel.log", "/var/log/osterman/daemon.log"],
+ "salvador": ["/var/log/salvador/sopel.log", "/var/log/salvador/daemon.log"],
+ "shireen": ["/var/log/shireen/sopel.log", "/var/log/shireen/daemon.log"],
+ "jeeves": ["/var/log/jeeves/sopel.log", "/var/log/jeeves/daemon.log"],
}
@@ -63,11 +76,13 @@ def _uptime(bot, _args):
def _disk(bot, _args):
- bot.say(_run(["df", "-h", "/"]))
+ for line in _run(["df", "-h", "/"]).splitlines():
+ bot.say(line)
def _mem(bot, _args):
- bot.say(_run(["free", "-h"]))
+ for line in _run(["free", "-h"]).splitlines():
+ bot.say(line)
def _load(bot, _args):
@@ -90,7 +105,7 @@ def _status(bot, args):
capture_output=True, text=True, timeout=5
)
out = (r.stdout + r.stderr).strip()
- state = "started" if "started" in out else "stopped" if "stopped" in out else out[:20]
+ state = "UP" if "started" in out else "DOWN" if "stopped" in out else out[:20]
results.append(f"{svc}:{state}")
bot.say(" | ".join(results))
@@ -201,12 +216,37 @@ def _io(bot, _args):
def _conns(bot, _args):
- bot.say(_run(["ss", "-s"]))
+ for line in _run(["ss", "-s"]).splitlines():
+ bot.say(line)
def _who(bot, _args):
out = _run(["who"])
- bot.say(out if out.strip() else "who: no users logged in")
+ if not out.strip() or out == "(no output)":
+ bot.say("who: no users logged in")
+ return
+ for line in out.splitlines():
+ bot.say(line)
+
+
+def _scan(bot, args):
+ path = args[0] if args else "/home/ahmed/mail"
+ allowed = ("/home/ahmed/mail", "/var/0x0/files", "/tmp", "/var/quarantine")
+ if not any(path.startswith(p) for p in allowed):
+ bot.say(f"scan: path not allowed: {path}")
+ return
+ bot.say(f"scan: starting clamscan on {path} ...")
+ r = subprocess.run(
+ ["clamscan", "-r", "--quiet", "--infected", path],
+ capture_output=True, text=True, timeout=300
+ )
+ out = (r.stdout + r.stderr).strip()
+ if not out:
+ bot.say("scan: no infected files found")
+ else:
+ for line in out.splitlines()[:15]:
+ bot.say(line)
+ bot.say(f"scan: done (exit {r.returncode})")
def _logs(bot, args):
@@ -244,6 +284,7 @@ _SUBCOMMANDS = {
"conns": _conns,
"who": _who,
"logs": _logs,
+ "scan": _scan,
}