| … | … | @@ -0,0 +1 @@ |
| 1 | node_modules/ |
| … | … | @@ -0,0 +1,71 @@ |
| 1 | # host-services | |
| 2 | ||
| 3 | One page that lists everything a host serves, with its state, plus the other | |
| 4 | devices on the LAN and what they serve. A Bare app deployed with pgh; it runs on | |
| 5 | stortron and Caddy fronts it as `http://stortron.local/`. | |
| 6 | ||
| 7 | ## What it shows | |
| 8 | ||
| 9 | **Services** (refreshed every ~15 s), each one **active**, **degraded** (running, | |
| 10 | but none of its ports answer), **dormant** (installed or enabled, not running) or | |
| 11 | **failed**: | |
| 12 | ||
| 13 | - every pgh app (`pgh app status`): version, autostart, last exit | |
| 14 | - systemd units, system and user. Hand-installed units (`/etc/systemd`, | |
| 15 | `~/.config/systemd`) are always listed; units the distribution shipped only when | |
| 16 | they own a port, are failed, or are named in `labels.json`. The rest is folded | |
| 17 | into "Operating-system units". | |
| 18 | - every listening TCP port, tied to its owner: our own processes through | |
| 19 | `/proc/<pid>/fd`; other users' sockets to the running unit with that `User=`; | |
| 20 | root's well-known ports through `labels.json` (`"unit"`). Anything left over is | |
| 21 | listed on its own, so nothing hides. Each port is probed: open, HTTP status, | |
| 22 | page title. | |
| 23 | ||
| 24 | **Network** (every 30 min, or "Scan now"): a TCP sweep of the host's /24 fills | |
| 25 | the ARP table (a device that drops all TCP still answers ARP), then mDNS names | |
| 26 | and advertised services from avahi, then a connect scan of ~95 common ports per | |
| 27 | device with an HTTP probe of each open one. No root needed. The last scan is | |
| 28 | kept in `~/.config/host-services/lan.json`. | |
| 29 | ||
| 30 | ## Run / test | |
| 31 | ||
| 32 | ```bash | |
| 33 | npm ci | |
| 34 | npm test # brittle-bare | |
| 35 | bare index.js # 127.0.0.1:4060 by default | |
| 36 | ``` | |
| 37 | ||
| 38 | Env: `HOST_SERVICES_PORT` (4060), `HOST_SERVICES_HOST` (127.0.0.1; the pgh | |
| 39 | defaults set 0.0.0.0), `HOST_SERVICES_CONFIG` (`~/.config/host-services`), | |
| 40 | `HOST_SERVICES_LAN_SCAN=0` to turn the periodic LAN scan off. | |
| 41 | ||
| 42 | Local labels: `~/.config/host-services/labels.json`, same shape as the shipped | |
| 43 | `labels.json`, merged over it key by key. | |
| 44 | ||
| 45 | Dependencies are pinned for pgh's Bare **1.28.7** (lockfile shared with | |
| 46 | cthuloid-web): newer `bare-dns` / `bare-type` / `bare-structured-clone` declare | |
| 47 | newer Bare engines and refuse to load. | |
| 48 | ||
| 49 | ⚠ On a dev machine run the real binary, not the npm `bare` wrapper: the wrapper | |
| 50 | does not forward SIGTERM, so `kill` leaves the app running. | |
| 51 | ||
| 52 | ## Deploy (pgh) | |
| 53 | ||
| 54 | ```bash | |
| 55 | pgh publish . # from this directory | |
| 56 | # on stortron: | |
| 57 | pgh app install pgh://1dd36bdfa9cb7f7d84adbd07f017e7200f7f90a3a546cd0761fac2a1f8a13e86/host-services --name host-services | |
| 58 | pgh app start host-services | |
| 59 | pgh app autostart host-services on | |
| 60 | ``` | |
| 61 | ||
| 62 | Caddy (`/etc/caddy/Caddyfile`) on stortron: | |
| 63 | ||
| 64 | ``` | |
| 65 | http://stortron.local { | |
| 66 | reverse_proxy 127.0.0.1:4060 | |
| 67 | } | |
| 68 | ``` | |
| 69 | ||
| 70 | ⛔ LAN-only, no login, like the services it lists. The one POST | |
| 71 | (`/api/lan/scan`) must carry `x-host-services: 1`. |
| … | … | @@ -0,0 +1,57 @@ |
| 1 | // host-services — `bare index.js`. One page listing everything this host | |
| 2 | // serves (pgh apps, systemd units, every listening port) with active / dormant | |
| 3 | // state, plus the other devices on the LAN and what they serve. | |
| 4 | // | |
| 5 | // ⛔ LAN-only, no login (the services it lists have none either). The pgh | |
| 6 | // defaults bind 0.0.0.0:4060 and Caddy fronts it as http://<host>.local/; the | |
| 7 | // code default is 127.0.0.1 so a bare `bare index.js` on a dev machine exposes | |
| 8 | // nothing. | |
| 9 | ||
| 10 | import fs from 'bare-fs' | |
| 11 | import os from 'bare-os' | |
| 12 | import path from 'bare-path' | |
| 13 | import process from 'bare-process' | |
| 14 | import { HostCollector } from './lib/collect.js' | |
| 15 | import { LanScanner } from './lib/lan.js' | |
| 16 | import { createServer } from './lib/server.js' | |
| 17 | ||
| 18 | const port = Number(process.env.HOST_SERVICES_PORT || 4060) | |
| 19 | const host = process.env.HOST_SERVICES_HOST || '127.0.0.1' | |
| 20 | const configDir = process.env.HOST_SERVICES_CONFIG || path.join(os.homedir(), '.config', 'host-services') | |
| 21 | const lanScan = process.env.HOST_SERVICES_LAN_SCAN !== '0' | |
| 22 | ||
| 23 | // Friendly names for known ports and units. The one shipped with the app, | |
| 24 | // overridden key-by-key by ~/.config/host-services/labels.json if present. | |
| 25 | function loadLabels () { | |
| 26 | const read = (p) => { | |
| 27 | try { | |
| 28 | return JSON.parse(fs.readFileSync(p).toString()) | |
| 29 | } catch { | |
| 30 | return {} | |
| 31 | } | |
| 32 | } | |
| 33 | const base = read(path.join(path.dirname(new URL(import.meta.url).pathname), 'labels.json')) | |
| 34 | const local = read(path.join(configDir, 'labels.json')) | |
| 35 | return { | |
| 36 | ports: { ...base.ports, ...local.ports }, | |
| 37 | units: { ...base.units, ...local.units } | |
| 38 | } | |
| 39 | } | |
| 40 | ||
| 41 | const collector = new HostCollector({ labels: loadLabels() }) | |
| 42 | const lan = new LanScanner({ configDir }) | |
| 43 | const server = createServer({ host: collector, lan }) | |
| 44 | ||
| 45 | server.listen(port, host, () => { | |
| 46 | console.log(JSON.stringify({ msg: 'host-services up', url: 'http://' + host + ':' + server.address().port, config: configDir, lanScan })) | |
| 47 | if (lanScan) lan.start() | |
| 48 | }) | |
| 49 | lan.on('scanned', (r) => console.log(JSON.stringify({ msg: 'lan scanned', hosts: r.hosts.length, ms: r.durationMs }))) | |
| 50 | ||
| 51 | const shutdown = () => { | |
| 52 | lan.stop() | |
| 53 | server.close(() => process.exit(0)) | |
| 54 | setTimeout(() => process.exit(0), 3000) | |
| 55 | } | |
| 56 | process.on('SIGTERM', shutdown) | |
| 57 | process.on('SIGINT', shutdown) |
| … | … | @@ -0,0 +1,104 @@ |
| 1 | { | |
| 2 | "ports": { | |
| 3 | "22": { | |
| 4 | "name": "SSH", | |
| 5 | "unit": "ssh.service" | |
| 6 | }, | |
| 7 | "53": { | |
| 8 | "name": "DNS (systemd-resolved)", | |
| 9 | "unit": "systemd-resolved.service" | |
| 10 | }, | |
| 11 | "80": { | |
| 12 | "name": "Caddy (HTTP)" | |
| 13 | }, | |
| 14 | "443": { | |
| 15 | "name": "Caddy (HTTPS)" | |
| 16 | }, | |
| 17 | "631": { | |
| 18 | "name": "CUPS printing", | |
| 19 | "unit": "cups.service" | |
| 20 | }, | |
| 21 | "2019": { | |
| 22 | "name": "Caddy admin API" | |
| 23 | }, | |
| 24 | "3399": { | |
| 25 | "name": "favela-gateway: atproto membrane" | |
| 26 | }, | |
| 27 | "3400": { | |
| 28 | "name": "favela-gateway: fediverse (ap.7rnx.net)" | |
| 29 | }, | |
| 30 | "3401": { | |
| 31 | "name": "favela-gateway: bridge sign-in" | |
| 32 | }, | |
| 33 | "4041": { | |
| 34 | "name": "favela-web" | |
| 35 | }, | |
| 36 | "4042": { | |
| 37 | "name": "favela-host" | |
| 38 | }, | |
| 39 | "4050": { | |
| 40 | "name": "Cthuloid Lights" | |
| 41 | }, | |
| 42 | "4060": { | |
| 43 | "name": "host-services (this page)" | |
| 44 | }, | |
| 45 | "5005": { | |
| 46 | "name": "pear-git-v3 forge" | |
| 47 | }, | |
| 48 | "5055": { | |
| 49 | "name": "Jellyseerr" | |
| 50 | }, | |
| 51 | "7220": { | |
| 52 | "name": "stremio-vsembed addon" | |
| 53 | }, | |
| 54 | "7221": { | |
| 55 | "name": "Kodi repo (jacktook dist)" | |
| 56 | }, | |
| 57 | "7878": { | |
| 58 | "name": "Radarr" | |
| 59 | }, | |
| 60 | "8081": { | |
| 61 | "name": "Easynews indexer bridge" | |
| 62 | }, | |
| 63 | "8085": { | |
| 64 | "name": "SABnzbd" | |
| 65 | }, | |
| 66 | "8096": { | |
| 67 | "name": "Jellyfin" | |
| 68 | }, | |
| 69 | "8920": { | |
| 70 | "name": "Jellyfin HTTPS (disabled)" | |
| 71 | }, | |
| 72 | "8989": { | |
| 73 | "name": "Sonarr" | |
| 74 | }, | |
| 75 | "9696": { | |
| 76 | "name": "Prowlarr" | |
| 77 | }, | |
| 78 | "32400": { | |
| 79 | "name": "Plex" | |
| 80 | }, | |
| 81 | "32401": { | |
| 82 | "name": "Plex (internal)" | |
| 83 | }, | |
| 84 | "32600": { | |
| 85 | "name": "Plex (internal)" | |
| 86 | }, | |
| 87 | "33445": { | |
| 88 | "name": "Plex (internal)" | |
| 89 | } | |
| 90 | }, | |
| 91 | "units": { | |
| 92 | "caddy.service": { | |
| 93 | "name": "Caddy", | |
| 94 | "description": "Reverse proxy for <host>.local" | |
| 95 | }, | |
| 96 | "hyperident-gateway.service": { | |
| 97 | "name": "hyperident-gateway", | |
| 98 | "description": "P2P VPN (10.22.0.0/16)" | |
| 99 | }, | |
| 100 | "smartmontools.service": { | |
| 101 | "name": "SMART disk monitor" | |
| 102 | } | |
| 103 | } | |
| 104 | } |
| … | … | @@ -0,0 +1,333 @@ |
| 1 | // Everything this host serves, in one snapshot: pgh apps, systemd units | |
| 2 | // (system and user) and every listening TCP port, each port tied to whoever | |
| 3 | // owns it, each service given a state: | |
| 4 | // | |
| 5 | // active running, and its ports (if any) answer | |
| 6 | // degraded running, but none of its ports answer | |
| 7 | // dormant installed / enabled but not running | |
| 8 | // failed systemd says failed, or a pgh app exited with an error | |
| 9 | // | |
| 10 | // Ownership of a socket: inode -> pid through /proc/<pid>/fd, which only works | |
| 11 | // for our own processes. Sockets of other users (jellyfin, plex, caddy...) are | |
| 12 | // tied by uid -> user -> the running unit with that User=. | |
| 13 | ||
| 14 | import fs from 'bare-fs' | |
| 15 | import os from 'bare-os' | |
| 16 | import path from 'bare-path' | |
| 17 | import process from 'bare-process' | |
| 18 | import { run } from './run.js' | |
| 19 | import { probeHttp } from './probe.js' | |
| 20 | import { parseProcNetTcp, bindScope, parseSystemctlShow, isVendorUnit, parsePghStatus } from './parse.js' | |
| 21 | ||
| 22 | const UNIT_PROPS = 'Id,Description,LoadState,ActiveState,SubState,UnitFileState,FragmentPath,MainPID,User,ActiveEnterTimestamp' | |
| 23 | ||
| 24 | function readText (p) { | |
| 25 | try { | |
| 26 | return fs.readFileSync(p).toString() | |
| 27 | } catch { | |
| 28 | return '' | |
| 29 | } | |
| 30 | } | |
| 31 | ||
| 32 | // The listening sockets, one entry per port+scope (a port bound on both | |
| 33 | // 0.0.0.0 and :: is one service, not two). | |
| 34 | export function readListeners (procRoot = '/proc') { | |
| 35 | const all = [ | |
| 36 | ...parseProcNetTcp(readText(path.join(procRoot, 'net/tcp')), 4), | |
| 37 | ...parseProcNetTcp(readText(path.join(procRoot, 'net/tcp6')), 6) | |
| 38 | ] | |
| 39 | const byPort = new Map() | |
| 40 | for (const l of all) { | |
| 41 | const scope = bindScope(l.addr) | |
| 42 | const key = l.port + '/' + (scope === 'addr' ? l.addr : scope) | |
| 43 | const prev = byPort.get(key) | |
| 44 | if (prev) { | |
| 45 | prev.inodes.push(l.inode) | |
| 46 | continue | |
| 47 | } | |
| 48 | byPort.set(key, { port: l.port, addr: l.addr, scope, uid: l.uid, inodes: [l.inode] }) | |
| 49 | } | |
| 50 | // A port open on all addresses also covers loopback: drop the 'local' twin. | |
| 51 | const out = [] | |
| 52 | for (const l of byPort.values()) { | |
| 53 | if (l.scope === 'local' && byPort.has(l.port + '/all')) { | |
| 54 | byPort.get(l.port + '/all').inodes.push(...l.inodes) | |
| 55 | continue | |
| 56 | } | |
| 57 | out.push(l) | |
| 58 | } | |
| 59 | return out.sort((a, b) => a.port - b.port) | |
| 60 | } | |
| 61 | ||
| 62 | // socket inode -> pid, for every process we may look into. | |
| 63 | export function socketOwners (procRoot = '/proc') { | |
| 64 | const owners = new Map() | |
| 65 | let pids = [] | |
| 66 | try { | |
| 67 | pids = fs.readdirSync(procRoot).filter((d) => /^\d+$/.test(d)) | |
| 68 | } catch {} | |
| 69 | for (const pid of pids) { | |
| 70 | let fds | |
| 71 | try { | |
| 72 | fds = fs.readdirSync(path.join(procRoot, pid, 'fd')) | |
| 73 | } catch { | |
| 74 | continue | |
| 75 | } | |
| 76 | for (const fd of fds) { | |
| 77 | let target | |
| 78 | try { | |
| 79 | target = fs.readlinkSync(path.join(procRoot, pid, 'fd', fd)) | |
| 80 | } catch { | |
| 81 | continue | |
| 82 | } | |
| 83 | const m = /^socket:\[(\d+)\]$/.exec(target) | |
| 84 | if (m) owners.set(Number(m[1]), Number(pid)) | |
| 85 | } | |
| 86 | } | |
| 87 | return owners | |
| 88 | } | |
| 89 | ||
| 90 | // What a pid is: a pgh app (by its install path), a systemd unit (by cgroup), | |
| 91 | // or just a command. | |
| 92 | export function describePid (pid, procRoot = '/proc') { | |
| 93 | const cmdline = readText(path.join(procRoot, String(pid), 'cmdline')).split('\0').filter(Boolean) | |
| 94 | const cgroup = readText(path.join(procRoot, String(pid), 'cgroup')) | |
| 95 | const unit = /\/([^/]+\.service)\s*$/m.exec(cgroup) | |
| 96 | const user = /user@\d+\.service/.test(cgroup) | |
| 97 | return { | |
| 98 | pid, | |
| 99 | cmd: cmdline.slice(0, 3).join(' ').slice(0, 200), | |
| 100 | exe: cmdline.length ? path.basename(cmdline[0]) : '', | |
| 101 | pghApp: pghAppOf(cmdline), | |
| 102 | unit: unit && !/^user@\d+\.service$/.test(unit[1]) ? unit[1] : null, | |
| 103 | userUnit: user | |
| 104 | } | |
| 105 | } | |
| 106 | ||
| 107 | // Every pgh app runs as `<store>/apps/pgh/runtime/bare <store>/apps/<app>/...`: | |
| 108 | // the app is the script's path, not the runtime's (which is always pgh's). | |
| 109 | export function pghAppOf (cmdline) { | |
| 110 | let app = null | |
| 111 | for (const arg of cmdline) { | |
| 112 | const m = /\/store\/apps\/([^/]+)\/(.*)$/.exec(arg) | |
| 113 | if (m && !m[2].startsWith('runtime/')) app = m[1] | |
| 114 | } | |
| 115 | return app | |
| 116 | } | |
| 117 | ||
| 118 | export function readUsers (passwd = readText('/etc/passwd')) { | |
| 119 | const users = new Map() | |
| 120 | for (const line of passwd.split('\n')) { | |
| 121 | const f = line.split(':') | |
| 122 | if (f.length > 2) users.set(Number(f[2]), f[0]) | |
| 123 | } | |
| 124 | return users | |
| 125 | } | |
| 126 | ||
| 127 | // Assemble the snapshot from raw inputs. Pure, so it is tested without a host. | |
| 128 | export function buildServices ({ listeners, owners, pidInfo, users, units, userUnits, pghApps, probes, labels = {} }) { | |
| 129 | const portLabels = labels.ports || {} | |
| 130 | const unitLabels = labels.units || {} | |
| 131 | const services = new Map() | |
| 132 | const add = (id, base) => { | |
| 133 | if (!services.has(id)) services.set(id, { id, ports: [], ...base }) | |
| 134 | return services.get(id) | |
| 135 | } | |
| 136 | ||
| 137 | for (const a of pghApps) { | |
| 138 | add('pgh:' + a.name, { | |
| 139 | kind: 'pgh', | |
| 140 | name: a.name, | |
| 141 | label: unitLabels['pgh:' + a.name] || null, | |
| 142 | running: a.running, | |
| 143 | version: a.version, | |
| 144 | autostart: a.autostart, | |
| 145 | since: a.running ? a.startedAt : a.lastExit, | |
| 146 | lastExitCode: a.lastExitCode, | |
| 147 | pid: a.pid | |
| 148 | }) | |
| 149 | } | |
| 150 | ||
| 151 | const unitById = new Map() | |
| 152 | for (const [scope, list] of [['system', units], ['user', userUnits]]) { | |
| 153 | for (const u of list) { | |
| 154 | if (u.LoadState && u.LoadState !== 'loaded') continue | |
| 155 | const id = (scope === 'user' ? 'user:' : 'unit:') + u.Id | |
| 156 | unitById.set(id, { scope, u }) | |
| 157 | } | |
| 158 | } | |
| 159 | ||
| 160 | // Which running unit runs as which user, for sockets we cannot look into. | |
| 161 | const unitsByUser = new Map() | |
| 162 | for (const [id, { u }] of unitById) { | |
| 163 | if (u.ActiveState !== 'active' || !u.User) continue | |
| 164 | if (!unitsByUser.has(u.User)) unitsByUser.set(u.User, []) | |
| 165 | unitsByUser.get(u.User).push(id) | |
| 166 | } | |
| 167 | ||
| 168 | const ensureUnit = (id) => { | |
| 169 | const rec = unitById.get(id) | |
| 170 | if (!rec) return null | |
| 171 | const { scope, u } = rec | |
| 172 | return add(id, { | |
| 173 | kind: scope === 'user' ? 'user-unit' : 'unit', | |
| 174 | name: u.Id.replace(/\.service$/, ''), | |
| 175 | label: unitLabels[u.Id] || null, | |
| 176 | description: u.Description && u.Description !== u.Id ? u.Description : null, | |
| 177 | running: u.ActiveState === 'active' || u.ActiveState === 'reloading', | |
| 178 | activeState: u.ActiveState, | |
| 179 | subState: u.SubState, | |
| 180 | enabled: u.UnitFileState, | |
| 181 | since: u.ActiveEnterTimestamp || null, | |
| 182 | user: u.User || null, | |
| 183 | vendor: isVendorUnit(u) | |
| 184 | }) | |
| 185 | } | |
| 186 | ||
| 187 | for (const l of listeners) { | |
| 188 | const probe = probes.get(l.port + '/' + l.addr) || null | |
| 189 | const port = { | |
| 190 | port: l.port, | |
| 191 | addr: l.addr, | |
| 192 | scope: l.scope, | |
| 193 | label: portLabels[String(l.port)] || null, | |
| 194 | open: probe ? probe.open : null, | |
| 195 | http: probe ? probe.http : null, | |
| 196 | banner: probe ? probe.banner : null, | |
| 197 | owner: null | |
| 198 | } | |
| 199 | let svc = null | |
| 200 | const pid = l.inodes.map((i) => owners.get(i)).find(Boolean) | |
| 201 | const info = pid ? (pidInfo.get(pid) || { pid, cmd: '', exe: '', pghApp: null, unit: null, userUnit: false }) : null | |
| 202 | if (info) { | |
| 203 | port.owner = { pid, cmd: info.cmd } | |
| 204 | if (info.pghApp && services.has('pgh:' + info.pghApp)) svc = services.get('pgh:' + info.pghApp) | |
| 205 | else if (info.unit) svc = ensureUnit((info.userUnit ? 'user:' : 'unit:') + info.unit) | |
| 206 | } else { | |
| 207 | const user = users.get(l.uid) || String(l.uid) | |
| 208 | port.owner = { user } | |
| 209 | const cands = unitsByUser.get(user) || [] | |
| 210 | if (cands.length === 1) svc = ensureUnit(cands[0]) | |
| 211 | } | |
| 212 | // Root's services run with an empty User=, so nothing above can tie them; | |
| 213 | // labels.json may name the unit a well-known port belongs to. | |
| 214 | if (!svc && port.label && port.label.unit && unitById.has('unit:' + port.label.unit)) svc = ensureUnit('unit:' + port.label.unit) | |
| 215 | // A plain process of ours (no unit, no pgh app): its ports belong together. | |
| 216 | if (!svc && info) { | |
| 217 | svc = add('proc:' + pid, { | |
| 218 | kind: 'process', | |
| 219 | name: info.exe || 'pid ' + pid, | |
| 220 | label: null, | |
| 221 | running: true, | |
| 222 | owner: port.owner | |
| 223 | }) | |
| 224 | } | |
| 225 | if (!svc) { | |
| 226 | svc = add('port:' + l.port + '/' + l.addr, { | |
| 227 | kind: 'port', | |
| 228 | name: (port.label && port.label.name) || (port.http && port.http.title) || 'port ' + l.port, | |
| 229 | label: port.label, | |
| 230 | running: true, | |
| 231 | owner: port.owner | |
| 232 | }) | |
| 233 | } | |
| 234 | svc.ports.push(port) | |
| 235 | } | |
| 236 | ||
| 237 | // Units nobody's port pulled in: hand-installed ones, labelled ones and | |
| 238 | // failed ones are services; the rest is the OS. | |
| 239 | const system = [] | |
| 240 | for (const [id, { u }] of unitById) { | |
| 241 | if (services.has(id)) continue | |
| 242 | const keep = !isVendorUnit(u) || unitLabels[u.Id] || u.ActiveState === 'failed' | |
| 243 | if (keep && (u.UnitFileState !== 'static' || u.ActiveState !== 'inactive')) ensureUnit(id) | |
| 244 | else system.push({ id, name: u.Id, state: u.ActiveState, sub: u.SubState, enabled: u.UnitFileState }) | |
| 245 | } | |
| 246 | ||
| 247 | const list = [...services.values()] | |
| 248 | for (const s of list) s.state = stateOf(s) | |
| 249 | return { services: list, system } | |
| 250 | } | |
| 251 | ||
| 252 | export function stateOf (s) { | |
| 253 | if (s.kind === 'unit' || s.kind === 'user-unit') { | |
| 254 | if (s.activeState === 'failed') return 'failed' | |
| 255 | if (!s.running) return 'dormant' | |
| 256 | } else if (s.kind === 'pgh') { | |
| 257 | // 75 is pgh's "restart into the new release" exit, not a failure. | |
| 258 | if (!s.running) return s.lastExitCode && s.lastExitCode !== 75 ? 'failed' : 'dormant' | |
| 259 | } | |
| 260 | if (s.ports.length && !s.ports.some((p) => p.open)) return 'degraded' | |
| 261 | return 'active' | |
| 262 | } | |
| 263 | ||
| 264 | export class HostCollector { | |
| 265 | constructor ({ labels = {}, pghBin = path.join(os.homedir(), '.local', 'bin', 'pgh'), ttlMs = 15000 } = {}) { | |
| 266 | this.labels = labels | |
| 267 | this.pghBin = pghBin | |
| 268 | this.ttlMs = ttlMs | |
| 269 | this._cache = null | |
| 270 | this._at = 0 | |
| 271 | this._inflight = null | |
| 272 | } | |
| 273 | ||
| 274 | snapshot () { | |
| 275 | if (this._cache && Date.now() - this._at < this.ttlMs) return Promise.resolve(this._cache) | |
| 276 | if (!this._inflight) { | |
| 277 | this._inflight = this._collect().then((s) => { | |
| 278 | this._cache = s | |
| 279 | this._at = Date.now() | |
| 280 | return s | |
| 281 | }).finally(() => { | |
| 282 | this._inflight = null | |
| 283 | }) | |
| 284 | } | |
| 285 | return this._inflight | |
| 286 | } | |
| 287 | ||
| 288 | async _collect () { | |
| 289 | const uid = process.getuid ? process.getuid() : 1000 | |
| 290 | // systemctl --user needs the session bus; a daemon started over ssh or by | |
| 291 | // pgh's supervisor may not have it in its environment. | |
| 292 | const userEnv = { ...process.env, XDG_RUNTIME_DIR: process.env.XDG_RUNTIME_DIR || '/run/user/' + uid } | |
| 293 | const [sys, usr, pgh] = await Promise.all([ | |
| 294 | run('systemctl', ['show', '--type=service', '--all', '-p', UNIT_PROPS]), | |
| 295 | run('systemctl', ['--user', 'show', '--type=service', '--all', '-p', UNIT_PROPS], { env: userEnv }), | |
| 296 | run(this.pghBin, ['app', 'status'], { timeoutMs: 20000 }) | |
| 297 | ]) | |
| 298 | const listeners = readListeners() | |
| 299 | const owners = socketOwners() | |
| 300 | const pidInfo = new Map() | |
| 301 | for (const pid of new Set(owners.values())) pidInfo.set(pid, describePid(pid)) | |
| 302 | ||
| 303 | const probes = new Map() | |
| 304 | await Promise.all(listeners.map(async (l) => { | |
| 305 | // Probe the address it listens on: a loopback listener may be on | |
| 306 | // 127.0.0.53, not 127.0.0.1. Wildcard listeners answer on 127.0.0.1. | |
| 307 | const host = l.scope === 'all' ? '127.0.0.1' : l.addr.replace(/^::ffff:/, '') | |
| 308 | probes.set(l.port + '/' + l.addr, await probeHttp(host, l.port)) | |
| 309 | })) | |
| 310 | ||
| 311 | const built = buildServices({ | |
| 312 | listeners, | |
| 313 | owners, | |
| 314 | pidInfo, | |
| 315 | users: readUsers(), | |
| 316 | units: parseSystemctlShow(sys.stdout), | |
| 317 | userUnits: parseSystemctlShow(usr.stdout), | |
| 318 | pghApps: parsePghStatus(pgh.stdout), | |
| 319 | probes, | |
| 320 | labels: this.labels | |
| 321 | }) | |
| 322 | return { | |
| 323 | host: os.hostname(), | |
| 324 | at: new Date().toISOString(), | |
| 325 | errors: [ | |
| 326 | sys.code !== 0 && 'systemctl: ' + (sys.stderr.trim() || 'exit ' + sys.code), | |
| 327 | usr.code !== 0 && 'systemctl --user: ' + (usr.stderr.trim() || 'exit ' + usr.code), | |
| 328 | pgh.code !== 0 && 'pgh app status: ' + (pgh.stderr.trim() || 'exit ' + pgh.code) | |
| 329 | ].filter(Boolean), | |
| 330 | ...built | |
| 331 | } | |
| 332 | } | |
| 333 | } |
| … | … | @@ -0,0 +1,168 @@ |
| 1 | // The rest of the LAN: which devices are up and what they serve. | |
| 2 | // | |
| 3 | // 1. Sweep every address of the host's /24 with a few TCP connects. Any reply, | |
| 4 | // even a refusal, makes the kernel learn the device's MAC, so afterwards | |
| 5 | // /proc/net/arp lists every device that answered ARP -- including ones that | |
| 6 | // drop all TCP (a firewalled Windows box still answers ARP). | |
| 7 | // 2. Names and advertised services from mDNS (avahi). | |
| 8 | // 3. A TCP connect scan of SCAN_PORTS on every device, then an HTTP probe of | |
| 9 | // each open port for its status and page title. | |
| 10 | // | |
| 11 | // Connect scans need no root. The result is kept on disk so a restart shows | |
| 12 | // the last scan at once. | |
| 13 | ||
| 14 | import fs from 'bare-fs' | |
| 15 | import path from 'bare-path' | |
| 16 | import EventEmitter from 'bare-events' | |
| 17 | import { run } from './run.js' | |
| 18 | import { tcpOpen, probeHttp } from './probe.js' | |
| 19 | import { parseArp, parseAvahiBrowse, parseIpAddr } from './parse.js' | |
| 20 | ||
| 21 | const SWEEP_PORTS = [80, 443, 22, 445, 139, 53, 8080, 5357, 62078, 9100] | |
| 22 | ||
| 23 | // Common service ports plus everything a full nmap top-1000 scan of this LAN | |
| 24 | // found open (2026-10-19). | |
| 25 | export const SCAN_PORTS = [ | |
| 26 | 21, 22, 23, 25, 53, 80, 81, 88, 110, 111, 135, 139, 143, 389, 443, 445, 515, | |
| 27 | 548, 554, 587, 631, 993, 995, 1080, 1194, 1400, 1883, 1900, 2049, 2179, 2375, | |
| 28 | 3000, 3001, 3128, 3306, 3389, 3399, 3400, 3401, 4040, 4041, 4042, 4050, 4060, | |
| 29 | 4443, 4445, 5000, 5001, 5005, 5055, 5060, 5357, 5432, 5900, 6379, 6443, 7000, | |
| 30 | 7220, 7221, 7878, 8000, 8001, 8008, 8009, 8020, 8080, 8081, 8085, 8086, 8088, | |
| 31 | 8096, 8123, 8181, 8200, 8443, 8800, 8888, 8920, 8989, 9000, 9001, 9090, 9091, | |
| 32 | 9100, 9117, 9696, 9999, 10000, 11434, 20005, 32400, 49152, 62078 | |
| 33 | ] | |
| 34 | ||
| 35 | const NO_HTTP_PROBE = new Set([21, 22, 23, 25, 53, 110, 111, 135, 139, 143, 445, 515, 1883, 2049, 3306, 3389, 5060, 5432, 5900, 6379, 9100]) | |
| 36 | ||
| 37 | async function pool (items, limit, fn) { | |
| 38 | const out = new Array(items.length) | |
| 39 | let next = 0 | |
| 40 | const worker = async () => { | |
| 41 | while (next < items.length) { | |
| 42 | const i = next++ | |
| 43 | out[i] = await fn(items[i], i) | |
| 44 | } | |
| 45 | } | |
| 46 | await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker)) | |
| 47 | return out | |
| 48 | } | |
| 49 | ||
| 50 | export class LanScanner extends EventEmitter { | |
| 51 | constructor ({ configDir, intervalMs = 30 * 60 * 1000, ports = SCAN_PORTS } = {}) { | |
| 52 | super() | |
| 53 | this.file = configDir ? path.join(configDir, 'lan.json') : null | |
| 54 | this.intervalMs = intervalMs | |
| 55 | this.ports = ports | |
| 56 | this.result = null | |
| 57 | this.scanning = false | |
| 58 | this.progress = '' | |
| 59 | this._timer = null | |
| 60 | this._load() | |
| 61 | } | |
| 62 | ||
| 63 | _load () { | |
| 64 | if (!this.file) return | |
| 65 | try { | |
| 66 | this.result = JSON.parse(fs.readFileSync(this.file).toString()) | |
| 67 | } catch {} | |
| 68 | } | |
| 69 | ||
| 70 | _save () { | |
| 71 | if (!this.file) return | |
| 72 | try { | |
| 73 | fs.mkdirSync(path.dirname(this.file), { recursive: true }) | |
| 74 | fs.writeFileSync(this.file + '.tmp', JSON.stringify(this.result)) | |
| 75 | fs.renameSync(this.file + '.tmp', this.file) | |
| 76 | } catch (err) { | |
| 77 | console.error(JSON.stringify({ msg: 'lan save failed', error: err.message })) | |
| 78 | } | |
| 79 | } | |
| 80 | ||
| 81 | start () { | |
| 82 | const age = this.result ? Date.now() - Date.parse(this.result.at) : Infinity | |
| 83 | const first = Math.max(0, Math.min(this.intervalMs - age, this.intervalMs)) | |
| 84 | this._timer = setTimeout(() => this._tick(), first) | |
| 85 | } | |
| 86 | ||
| 87 | stop () { | |
| 88 | clearTimeout(this._timer) | |
| 89 | this._timer = null | |
| 90 | } | |
| 91 | ||
| 92 | _tick () { | |
| 93 | this.scan().finally(() => { | |
| 94 | if (this._timer !== null) this._timer = setTimeout(() => this._tick(), this.intervalMs) | |
| 95 | }) | |
| 96 | } | |
| 97 | ||
| 98 | state () { | |
| 99 | return { scanning: this.scanning, progress: this.progress, result: this.result } | |
| 100 | } | |
| 101 | ||
| 102 | async scan () { | |
| 103 | if (this.scanning) return this.result | |
| 104 | this.scanning = true | |
| 105 | const started = Date.now() | |
| 106 | try { | |
| 107 | this.progress = 'finding the LAN' | |
| 108 | const own = parseIpAddr((await run('ip', ['-4', '-o', 'addr', 'show', 'scope', 'global'])).stdout) | |
| 109 | .filter((a) => !/^(tun|tunnel|wg|docker|br-|veth|virbr)/.test(a.dev) && a.prefix >= 16 && a.prefix <= 30) | |
| 110 | const subnets = [...new Set(own.map((a) => a.ip.split('.').slice(0, 3).join('.')))] | |
| 111 | ||
| 112 | this.progress = 'sweeping ' + subnets.map((s) => s + '.0/24').join(', ') | |
| 113 | const sweep = [] | |
| 114 | for (const s of subnets) for (let i = 1; i < 255; i++) for (const p of SWEEP_PORTS) sweep.push([s + '.' + i, p]) | |
| 115 | await pool(sweep, 256, ([h, p]) => tcpOpen(h, p, 500)) | |
| 116 | ||
| 117 | const arp = parseArp(fs.readFileSync('/proc/net/arp').toString()) | |
| 118 | .filter((a) => subnets.some((s) => a.ip.startsWith(s + '.'))) | |
| 119 | const hosts = new Map() | |
| 120 | for (const a of own) hosts.set(a.ip, { ip: a.ip, mac: null, self: true, names: [], mdns: [], ports: [] }) | |
| 121 | for (const a of arp) if (!hosts.has(a.ip)) hosts.set(a.ip, { ip: a.ip, mac: a.mac, self: false, names: [], mdns: [], ports: [] }) | |
| 122 | ||
| 123 | this.progress = 'mDNS names and services' | |
| 124 | const [browse] = await Promise.all([ | |
| 125 | run('avahi-browse', ['-a', '-t', '-r', '-p', '--no-db-lookup'], { timeoutMs: 12000 }), | |
| 126 | pool([...hosts.values()], 16, async (h) => { | |
| 127 | const r = await run('avahi-resolve', ['-a', h.ip], { timeoutMs: 3000 }) | |
| 128 | const name = r.stdout.trim().split(/\s+/)[1] | |
| 129 | if (name) h.names.push(name) | |
| 130 | }) | |
| 131 | ]) | |
| 132 | for (const svc of parseAvahiBrowse(browse.stdout)) { | |
| 133 | const h = hosts.get(svc.ip) | |
| 134 | if (!h) continue | |
| 135 | if (!h.names.includes(svc.host)) h.names.push(svc.host) | |
| 136 | if (!h.mdns.some((m) => m.type === svc.type && m.port === svc.port && m.name === svc.name)) { | |
| 137 | h.mdns.push({ name: svc.name, type: svc.type, port: svc.port }) | |
| 138 | } | |
| 139 | } | |
| 140 | ||
| 141 | const list = [...hosts.values()] | |
| 142 | this.progress = 'port scan of ' + list.length + ' devices' | |
| 143 | const jobs = [] | |
| 144 | for (const h of list) for (const p of this.ports) jobs.push([h, p]) | |
| 145 | const open = await pool(jobs, 192, async ([h, p]) => ((await tcpOpen(h.ip, p, 800)) ? [h, p] : null)) | |
| 146 | ||
| 147 | this.progress = 'reading what answers' | |
| 148 | await pool(open.filter(Boolean), 32, async ([h, p]) => { | |
| 149 | if (NO_HTTP_PROBE.has(p)) return h.ports.push({ port: p, http: null, banner: null }) | |
| 150 | const r = await probeHttp(h.ip, p, { timeoutMs: 3000 }) | |
| 151 | h.ports.push({ port: p, http: r.http, banner: r.banner }) | |
| 152 | }) | |
| 153 | for (const h of list) h.ports.sort((a, b) => a.port - b.port) | |
| 154 | list.sort((a, b) => Number(a.ip.split('.')[3]) - Number(b.ip.split('.')[3])) | |
| 155 | ||
| 156 | this.result = { at: new Date().toISOString(), durationMs: Date.now() - started, subnets, ports: this.ports.length, hosts: list } | |
| 157 | this._save() | |
| 158 | this.emit('scanned', this.result) | |
| 159 | return this.result | |
| 160 | } catch (err) { | |
| 161 | console.error(JSON.stringify({ msg: 'lan scan failed', error: err.stack || String(err) })) | |
| 162 | return this.result | |
| 163 | } finally { | |
| 164 | this.scanning = false | |
| 165 | this.progress = '' | |
| 166 | } | |
| 167 | } | |
| 168 | } |
| … | … | @@ -0,0 +1,190 @@ |
| 1 | // Pure parsers for what the host tells us: /proc/net, systemctl, pgh, avahi, | |
| 2 | // HTTP. No I/O here, so every one of them is tested against captured output. | |
| 3 | ||
| 4 | // /proc/net/tcp and tcp6: LISTEN rows only (st 0A). Addresses are hex in host | |
| 5 | // byte order per 32-bit word, so 0100007F is 127.0.0.1. | |
| 6 | export function parseProcNetTcp (text, family = 4) { | |
| 7 | const out = [] | |
| 8 | for (const line of text.split('\n').slice(1)) { | |
| 9 | const f = line.trim().split(/\s+/) | |
| 10 | if (f.length < 10 || f[3] !== '0A') continue | |
| 11 | const [addrHex, portHex] = f[1].split(':') | |
| 12 | out.push({ | |
| 13 | family, | |
| 14 | addr: family === 4 ? ipv4FromHex(addrHex) : ipv6FromHex(addrHex), | |
| 15 | port: parseInt(portHex, 16), | |
| 16 | uid: Number(f[7]), | |
| 17 | inode: Number(f[9]) | |
| 18 | }) | |
| 19 | } | |
| 20 | return out | |
| 21 | } | |
| 22 | ||
| 23 | function ipv4FromHex (hex) { | |
| 24 | const n = parseInt(hex, 16) | |
| 25 | return [n & 255, (n >>> 8) & 255, (n >>> 16) & 255, (n >>> 24) & 255].join('.') | |
| 26 | } | |
| 27 | ||
| 28 | function ipv6FromHex (hex) { | |
| 29 | // Four little-endian 32-bit words. | |
| 30 | const bytes = [] | |
| 31 | for (let w = 0; w < 4; w++) { | |
| 32 | const word = hex.slice(w * 8, w * 8 + 8) | |
| 33 | for (let b = 3; b >= 0; b--) bytes.push(word.slice(b * 2, b * 2 + 2)) | |
| 34 | } | |
| 35 | const groups = [] | |
| 36 | for (let i = 0; i < 16; i += 2) groups.push(parseInt(bytes[i] + bytes[i + 1], 16).toString(16)) | |
| 37 | const full = groups.join(':') | |
| 38 | if (full === '0:0:0:0:0:0:0:0') return '::' | |
| 39 | if (full === '0:0:0:0:0:0:0:1') return '::1' | |
| 40 | if (full.startsWith('0:0:0:0:0:ffff:')) { | |
| 41 | const v4 = bytes.slice(12).map((h) => parseInt(h, 16)).join('.') | |
| 42 | return '::ffff:' + v4 | |
| 43 | } | |
| 44 | return full | |
| 45 | } | |
| 46 | ||
| 47 | // Listening on every address, loopback only, or one specific address. | |
| 48 | export function bindScope (addr) { | |
| 49 | if (addr === '0.0.0.0' || addr === '::') return 'all' | |
| 50 | if (addr.startsWith('127.') || addr === '::1') return 'local' | |
| 51 | return 'addr' | |
| 52 | } | |
| 53 | ||
| 54 | // `systemctl show -p A,B,...` for many units: blank-line-separated blocks of | |
| 55 | // Key=Value. | |
| 56 | export function parseSystemctlShow (text) { | |
| 57 | const units = [] | |
| 58 | let cur = {} | |
| 59 | for (const line of text.split('\n')) { | |
| 60 | if (line.trim() === '') { | |
| 61 | if (cur.Id) units.push(cur) | |
| 62 | cur = {} | |
| 63 | continue | |
| 64 | } | |
| 65 | const i = line.indexOf('=') | |
| 66 | if (i > 0) cur[line.slice(0, i)] = line.slice(i + 1) | |
| 67 | } | |
| 68 | if (cur.Id) units.push(cur) | |
| 69 | return units | |
| 70 | } | |
| 71 | ||
| 72 | // A unit the distribution shipped (under /usr/lib or /lib) vs one somebody | |
| 73 | // installed by hand (/etc/systemd, ~/.config/systemd). Hand-made ones are | |
| 74 | // always services worth listing; shipped ones only when they do something | |
| 75 | // visible (own a port) or are named in labels.json. | |
| 76 | export function isVendorUnit (u) { | |
| 77 | const p = u.FragmentPath || '' | |
| 78 | return p.startsWith('/usr/lib/') || p.startsWith('/lib/') || p.startsWith('/usr/share/') | |
| 79 | } | |
| 80 | ||
| 81 | // `pgh app status` prints a fixed-width table: header, a dashes row, then one | |
| 82 | // row per app. Column edges come from the dashes row, so values with spaces | |
| 83 | // (none today) would still split correctly. | |
| 84 | export function parsePghStatus (text) { | |
| 85 | const lines = text.split('\n') | |
| 86 | const di = lines.findIndex((l) => /^-+(\s+-+)+\s*$/.test(l)) | |
| 87 | if (di < 1) return [] | |
| 88 | const header = lines[di - 1] | |
| 89 | const cols = [] | |
| 90 | const re = /-+/g | |
| 91 | let m | |
| 92 | while ((m = re.exec(lines[di])) !== null) cols.push([m.index, m.index + m[0].length]) | |
| 93 | const names = cols.map(([a, b], i) => header.slice(a, i + 1 < cols.length ? cols[i + 1][0] : undefined).trim()) | |
| 94 | const apps = [] | |
| 95 | for (const line of lines.slice(di + 1)) { | |
| 96 | if (!line.trim()) continue | |
| 97 | const row = {} | |
| 98 | cols.forEach(([a], i) => { | |
| 99 | const end = i + 1 < cols.length ? cols[i + 1][0] : undefined | |
| 100 | row[names[i]] = line.slice(a, end).trim() | |
| 101 | }) | |
| 102 | if (!row.name) continue | |
| 103 | apps.push({ | |
| 104 | name: row.name, | |
| 105 | running: row.running === 'true', | |
| 106 | pid: Number(row.childPid) || null, | |
| 107 | version: row.version || '', | |
| 108 | startedAt: row.startedAt || null, | |
| 109 | lastExit: row.lastExit || null, | |
| 110 | lastExitCode: row.lastExitCode === '' ? null : Number(row.lastExitCode), | |
| 111 | autostart: row.autostart === 'true' | |
| 112 | }) | |
| 113 | } | |
| 114 | return apps | |
| 115 | } | |
| 116 | ||
| 117 | // The first lines of a raw HTTP/1.x response: status code, Location, <title>. | |
| 118 | // null when the bytes are not HTTP at all (an SSH banner, a binary protocol). | |
| 119 | export function parseHttpHead (text) { | |
| 120 | const m = /^HTTP\/\d(?:\.\d)?\s+(\d{3})/.exec(text) | |
| 121 | if (!m) return null | |
| 122 | const loc = /\r?\nlocation:\s*([^\r\n]+)/i.exec(text) | |
| 123 | const server = /\r?\nserver:\s*([^\r\n]+)/i.exec(text) | |
| 124 | return { | |
| 125 | code: Number(m[1]), | |
| 126 | location: loc ? loc[1].trim() : null, | |
| 127 | server: server ? server[1].trim() : null, | |
| 128 | title: extractTitle(text) | |
| 129 | } | |
| 130 | } | |
| 131 | ||
| 132 | export function extractTitle (html) { | |
| 133 | const m = /<title[^>]*>([^<]*)/i.exec(html) | |
| 134 | if (!m) return null | |
| 135 | const t = decodeEntities(m[1]).replace(/\s+/g, ' ').trim() | |
| 136 | return t || null | |
| 137 | } | |
| 138 | ||
| 139 | function decodeEntities (s) { | |
| 140 | return s.replace(/&(amp|lt|gt|quot|#39|#x27|middot|nbsp);/g, (_, e) => ({ | |
| 141 | amp: '&', lt: '<', gt: '>', quot: '"', '#39': "'", '#x27': "'", middot: '·', nbsp: ' ' | |
| 142 | })[e]) | |
| 143 | } | |
| 144 | ||
| 145 | // /proc/net/arp: complete entries only (flags 0x2); 0x0 rows are hosts that | |
| 146 | // never answered. | |
| 147 | export function parseArp (text) { | |
| 148 | const out = [] | |
| 149 | for (const line of text.split('\n').slice(1)) { | |
| 150 | const f = line.trim().split(/\s+/) | |
| 151 | if (f.length < 6) continue | |
| 152 | if (f[2] !== '0x2' && f[2] !== '0x6') continue | |
| 153 | if (f[3] === '00:00:00:00:00:00') continue | |
| 154 | out.push({ ip: f[0], mac: f[3].toLowerCase(), dev: f[5] }) | |
| 155 | } | |
| 156 | return out | |
| 157 | } | |
| 158 | ||
| 159 | // avahi's parsable output escapes bytes as \DDD (decimal) and specials as \c. | |
| 160 | function avahiUnescape (s) { | |
| 161 | return s.replace(/\\(\d{3}|.)/g, (_, e) => (e.length === 3 ? String.fromCharCode(Number(e)) : e)) | |
| 162 | } | |
| 163 | ||
| 164 | // `avahi-browse -atrp`: resolved ('=') IPv4 rows -> one service each. | |
| 165 | export function parseAvahiBrowse (text) { | |
| 166 | const out = [] | |
| 167 | for (const line of text.split('\n')) { | |
| 168 | const f = line.split(';') | |
| 169 | if (f[0] !== '=' || f.length < 10 || f[2] !== 'IPv4') continue | |
| 170 | out.push({ | |
| 171 | name: avahiUnescape(f[3]), | |
| 172 | type: f[4], | |
| 173 | host: avahiUnescape(f[6]), | |
| 174 | ip: f[7], | |
| 175 | port: Number(f[8]), | |
| 176 | txt: f.slice(9).join(';') | |
| 177 | }) | |
| 178 | } | |
| 179 | return out | |
| 180 | } | |
| 181 | ||
| 182 | // `ip -4 -o addr show scope global`: the host's own LAN addresses + prefix. | |
| 183 | export function parseIpAddr (text) { | |
| 184 | const out = [] | |
| 185 | for (const line of text.split('\n')) { | |
| 186 | const m = /^\d+:\s+(\S+)\s+inet\s+(\d+\.\d+\.\d+\.\d+)\/(\d+)/.exec(line) | |
| 187 | if (m) out.push({ dev: m[1], ip: m[2], prefix: Number(m[3]) }) | |
| 188 | } | |
| 189 | return out | |
| 190 | } |
| … | … | @@ -0,0 +1,64 @@ |
| 1 | // What answers on a TCP port: open or not, and if it speaks HTTP, the status, | |
| 2 | // redirect and page title. | |
| 3 | // | |
| 4 | // A raw socket and a hand-written GET rather than an HTTP client: the port may | |
| 5 | // speak anything (SSH, SIP, a binary protocol), and all we want is the first | |
| 6 | // few KB, read with one hard deadline. | |
| 7 | ||
| 8 | import net from 'bare-net' | |
| 9 | import { parseHttpHead } from './parse.js' | |
| 10 | ||
| 11 | const READ_LIMIT = 64 * 1024 | |
| 12 | ||
| 13 | // Is anything listening? Resolves true/false, never rejects. | |
| 14 | export function tcpOpen (host, port, timeoutMs = 700) { | |
| 15 | return new Promise((resolve) => { | |
| 16 | let done = false | |
| 17 | const sock = net.createConnection(port, host) | |
| 18 | const finish = (ok) => { | |
| 19 | if (done) return | |
| 20 | done = true | |
| 21 | clearTimeout(timer) | |
| 22 | sock.destroy() | |
| 23 | resolve(ok) | |
| 24 | } | |
| 25 | const timer = setTimeout(() => finish(false), timeoutMs) | |
| 26 | sock.on('connect', () => finish(true)) | |
| 27 | sock.on('error', () => finish(false)) | |
| 28 | }) | |
| 29 | } | |
| 30 | ||
| 31 | // { open, http: { code, location, server, title } | null, banner } | |
| 32 | export function probeHttp (host, port, { timeoutMs = 2500, hostHeader = host } = {}) { | |
| 33 | return new Promise((resolve) => { | |
| 34 | let done = false | |
| 35 | let open = false | |
| 36 | const chunks = [] | |
| 37 | let size = 0 | |
| 38 | const sock = net.createConnection(port, host) | |
| 39 | const finish = () => { | |
| 40 | if (done) return | |
| 41 | done = true | |
| 42 | clearTimeout(timer) | |
| 43 | sock.destroy() | |
| 44 | const text = Buffer.concat(chunks).toString('latin1') | |
| 45 | const http = parseHttpHead(text) | |
| 46 | const banner = http ? null : text.split(/\r?\n/)[0].slice(0, 120) || null | |
| 47 | resolve({ open, http, banner }) | |
| 48 | } | |
| 49 | const timer = setTimeout(finish, timeoutMs) | |
| 50 | sock.on('connect', () => { | |
| 51 | open = true | |
| 52 | sock.write('GET / HTTP/1.0\r\nHost: ' + hostHeader + ':' + port + '\r\nUser-Agent: host-services\r\nAccept: text/html\r\nConnection: close\r\n\r\n') | |
| 53 | }) | |
| 54 | sock.on('data', (d) => { | |
| 55 | chunks.push(d) | |
| 56 | size += d.length | |
| 57 | // Enough to see the head and a <title>; stop reading big pages. | |
| 58 | if (size >= READ_LIMIT || /<\/title>/i.test(d.toString('latin1'))) finish() | |
| 59 | }) | |
| 60 | sock.on('end', finish) | |
| 61 | sock.on('close', finish) | |
| 62 | sock.on('error', finish) | |
| 63 | }) | |
| 64 | } |
| … | … | @@ -0,0 +1,53 @@ |
| 1 | // Run a command, collect stdout, never hang. | |
| 2 | // | |
| 3 | // Launched via `sh -c 'exec "$0" "$@"'` (as cthuloid-web's discovery does): in | |
| 4 | // bare-subprocess 6.1.0 a spawn of a missing binary throws ENOENT AFTER | |
| 5 | // creating its stdio pipes and never closes them. sh always exists; a missing | |
| 6 | // command becomes exit 127 instead. | |
| 7 | ||
| 8 | import { spawn } from 'bare-subprocess' | |
| 9 | ||
| 10 | export function run (cmd, args = [], { timeoutMs = 15000, maxBytes = 4 * 1024 * 1024, env = null } = {}) { | |
| 11 | return new Promise((resolve) => { | |
| 12 | let proc | |
| 13 | try { | |
| 14 | const opts = { stdio: ['ignore', 'pipe', 'pipe'] } | |
| 15 | if (env) opts.env = env | |
| 16 | proc = spawn('/bin/sh', ['-c', 'exec "$0" "$@"', cmd, ...args], opts) | |
| 17 | } catch (err) { | |
| 18 | return resolve({ code: -1, stdout: '', stderr: err.message || String(err) }) | |
| 19 | } | |
| 20 | const out = [] | |
| 21 | const errs = [] | |
| 22 | let size = 0 | |
| 23 | let done = false | |
| 24 | const finish = (code) => { | |
| 25 | if (done) return | |
| 26 | done = true | |
| 27 | clearTimeout(timer) | |
| 28 | resolve({ code, stdout: Buffer.concat(out).toString(), stderr: Buffer.concat(errs).toString() }) | |
| 29 | } | |
| 30 | const timer = setTimeout(() => { | |
| 31 | try { proc.kill() } catch {} | |
| 32 | finish(-2) | |
| 33 | }, timeoutMs) | |
| 34 | // 'exit' can arrive before the last stdout chunk: finish only when both | |
| 35 | // the process has exited and its stdout has ended. | |
| 36 | let exitCode = null | |
| 37 | let ended = false | |
| 38 | proc.stdout.on('data', (d) => { | |
| 39 | size += d.length | |
| 40 | if (size <= maxBytes) out.push(d) | |
| 41 | }) | |
| 42 | proc.stdout.on('end', () => { | |
| 43 | ended = true | |
| 44 | if (exitCode !== null) finish(exitCode) | |
| 45 | }) | |
| 46 | proc.stderr.on('data', (d) => errs.push(d)) | |
| 47 | proc.on('error', () => finish(-1)) | |
| 48 | proc.on('exit', (code) => { | |
| 49 | exitCode = code | |
| 50 | if (ended) finish(code) | |
| 51 | }) | |
| 52 | }) | |
| 53 | } |
| … | … | @@ -0,0 +1,63 @@ |
| 1 | // HTTP surface: the page, and a read-only JSON API. | |
| 2 | // | |
| 3 | // GET /api/host this host's services (cached ~15 s) | |
| 4 | // GET /api/lan the last LAN scan + whether one is running | |
| 5 | // POST /api/lan/scan start a LAN scan now | |
| 6 | // | |
| 7 | // ⛔ No login: LAN-only, like the services it lists. The one POST must carry | |
| 8 | // `x-host-services: 1` -- a cross-site page cannot add a custom header without | |
| 9 | // a CORS preflight, and this server never answers one. | |
| 10 | ||
| 11 | import http from 'bare-http1' | |
| 12 | import fs from 'bare-fs' | |
| 13 | import path from 'bare-path' | |
| 14 | ||
| 15 | const STATIC_DIR = path.join(path.dirname(new URL(import.meta.url).pathname), '..', 'static') | |
| 16 | const ASSETS = { | |
| 17 | '/': ['index.html', 'text/html; charset=utf-8'], | |
| 18 | '/index.html': ['index.html', 'text/html; charset=utf-8'], | |
| 19 | '/app.js': ['app.js', 'text/javascript; charset=utf-8'], | |
| 20 | '/app.css': ['app.css', 'text/css; charset=utf-8'] | |
| 21 | } | |
| 22 | ||
| 23 | function sendJSON (res, status, obj) { | |
| 24 | const body = JSON.stringify(obj) | |
| 25 | res.writeHead(status, { 'content-type': 'application/json', 'content-length': Buffer.byteLength(body), 'cache-control': 'no-store' }) | |
| 26 | res.end(body) | |
| 27 | } | |
| 28 | ||
| 29 | export function createServer ({ host, lan }) { | |
| 30 | return http.createServer((req, res) => { | |
| 31 | const url = req.url.split('?')[0] | |
| 32 | ||
| 33 | if (url === '/api/host' && req.method === 'GET') { | |
| 34 | host.snapshot().then((s) => sendJSON(res, 200, s), (err) => { | |
| 35 | console.error('host snapshot failed: ' + (err.stack || err)) | |
| 36 | sendJSON(res, 500, { error: err.message }) | |
| 37 | }) | |
| 38 | return | |
| 39 | } | |
| 40 | if (url === '/api/lan' && req.method === 'GET') return sendJSON(res, 200, lan.state()) | |
| 41 | if (url === '/api/lan/scan' && req.method === 'POST') { | |
| 42 | if (req.headers['x-host-services'] !== '1') return sendJSON(res, 403, { error: 'missing x-host-services header' }) | |
| 43 | lan.scan() | |
| 44 | return sendJSON(res, 202, { ok: true, scanning: true }) | |
| 45 | } | |
| 46 | if (url.startsWith('/api/')) return sendJSON(res, 404, { error: 'not found' }) | |
| 47 | ||
| 48 | const asset = ASSETS[url] | |
| 49 | if (!asset || req.method !== 'GET') { | |
| 50 | res.writeHead(404, { 'content-type': 'text/plain' }) | |
| 51 | return res.end('not found') | |
| 52 | } | |
| 53 | let body | |
| 54 | try { | |
| 55 | body = fs.readFileSync(path.join(STATIC_DIR, asset[0])) | |
| 56 | } catch { | |
| 57 | res.writeHead(500, { 'content-type': 'text/plain' }) | |
| 58 | return res.end('asset missing: ' + asset[0]) | |
| 59 | } | |
| 60 | res.writeHead(200, { 'content-type': asset[1], 'content-length': body.length, 'cache-control': 'no-cache' }) | |
| 61 | res.end(body) | |
| 62 | }) | |
| 63 | } |
| … | … | @@ -0,0 +1,1021 @@ |
| 1 | { | |
| 2 | "name": "host-services", | |
| 3 | "version": "0.1.0", | |
| 4 | "lockfileVersion": 3, | |
| 5 | "requires": true, | |
| 6 | "packages": { | |
| 7 | "": { | |
| 8 | "name": "host-services", | |
| 9 | "version": "0.1.0", | |
| 10 | "dependencies": { | |
| 11 | "bare-events": "2.9.2", | |
| 12 | "bare-fs": "4.8.2", | |
| 13 | "bare-http1": "4.6.2", | |
| 14 | "bare-net": "2.3.3", | |
| 15 | "bare-os": "3.9.3", | |
| 16 | "bare-path": "3.1.2", | |
| 17 | "bare-process": "4.5.1", | |
| 18 | "bare-subprocess": "6.1.0" | |
| 19 | }, | |
| 20 | "bin": { | |
| 21 | "host-services": "index.js" | |
| 22 | }, | |
| 23 | "devDependencies": { | |
| 24 | "brittle": "4.1.1" | |
| 25 | } | |
| 26 | }, | |
| 27 | "node_modules/@jridgewell/resolve-uri": { | |
| 28 | "version": "3.1.2", | |
| 29 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", | |
| 30 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", | |
| 31 | "dev": true, | |
| 32 | "license": "MIT", | |
| 33 | "engines": { | |
| 34 | "node": ">=6.0.0" | |
| 35 | } | |
| 36 | }, | |
| 37 | "node_modules/@jridgewell/sourcemap-codec": { | |
| 38 | "version": "1.6.0", | |
| 39 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", | |
| 40 | "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", | |
| 41 | "dev": true, | |
| 42 | "license": "MIT" | |
| 43 | }, | |
| 44 | "node_modules/@jridgewell/trace-mapping": { | |
| 45 | "version": "0.3.31", | |
| 46 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", | |
| 47 | "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", | |
| 48 | "dev": true, | |
| 49 | "license": "MIT", | |
| 50 | "dependencies": { | |
| 51 | "@jridgewell/resolve-uri": "^3.1.0", | |
| 52 | "@jridgewell/sourcemap-codec": "^1.4.14" | |
| 53 | } | |
| 54 | }, | |
| 55 | "node_modules/@types/istanbul-lib-coverage": { | |
| 56 | "version": "2.0.6", | |
| 57 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", | |
| 58 | "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", | |
| 59 | "dev": true, | |
| 60 | "license": "MIT" | |
| 61 | }, | |
| 62 | "node_modules/b4a": { | |
| 63 | "version": "1.9.0", | |
| 64 | "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.9.0.tgz", | |
| 65 | "integrity": "sha512-dpfcF9fDNR6++cthXR67iyhgqWy9CBouAvIWhIntzBG6cvK/cnIPiZQjBwi/ZqjjBEDGfoNDtmB0kTjroOJ3pQ==", | |
| 66 | "license": "Apache-2.0", | |
| 67 | "peerDependencies": { | |
| 68 | "react-native-b4a": "*" | |
| 69 | }, | |
| 70 | "peerDependenciesMeta": { | |
| 71 | "react-native-b4a": { | |
| 72 | "optional": true | |
| 73 | } | |
| 74 | } | |
| 75 | }, | |
| 76 | "node_modules/bare-abort": { | |
| 77 | "version": "2.0.13", | |
| 78 | "resolved": "https://registry.npmjs.org/bare-abort/-/bare-abort-2.0.13.tgz", | |
| 79 | "integrity": "sha512-zdc8l88eB11Jsz5rDd6sCAgv2kUFXgdrZWoMlgU6JMkfAi1/uuGFC3IEHswKbIRQTk5H3T5CMuechsXYxiaHlQ==", | |
| 80 | "license": "Apache-2.0" | |
| 81 | }, | |
| 82 | "node_modules/bare-addon-resolve": { | |
| 83 | "version": "1.10.1", | |
| 84 | "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.10.1.tgz", | |
| 85 | "integrity": "sha512-F/SD2du8keuYSb4xipnGz5j2E6yhNdHA8ZVxtHae6h2uOrpBIjjbhXvjzKZbr5XUOzqBzh/i8GVFycj2DlFQIA==", | |
| 86 | "dev": true, | |
| 87 | "license": "Apache-2.0", | |
| 88 | "dependencies": { | |
| 89 | "bare-module-resolve": "^1.10.0", | |
| 90 | "bare-semver": "^1.0.0" | |
| 91 | }, | |
| 92 | "peerDependencies": { | |
| 93 | "bare-url": "*" | |
| 94 | }, | |
| 95 | "peerDependenciesMeta": { | |
| 96 | "bare-url": { | |
| 97 | "optional": true | |
| 98 | } | |
| 99 | } | |
| 100 | }, | |
| 101 | "node_modules/bare-ansi-escapes": { | |
| 102 | "version": "2.2.3", | |
| 103 | "resolved": "https://registry.npmjs.org/bare-ansi-escapes/-/bare-ansi-escapes-2.2.3.tgz", | |
| 104 | "integrity": "sha512-02ES4/E2RbrtZSnHJ9LntBhYkLA6lPpSEeP8iqS3MccBIVhVBlEmruF1I7HZqx5Q8aiTeYfQVeqmrU9YO2yYoQ==", | |
| 105 | "dev": true, | |
| 106 | "license": "Apache-2.0", | |
| 107 | "dependencies": { | |
| 108 | "bare-stream": "^2.6.5" | |
| 109 | }, | |
| 110 | "peerDependencies": { | |
| 111 | "bare-buffer": "*" | |
| 112 | }, | |
| 113 | "peerDependenciesMeta": { | |
| 114 | "bare-buffer": { | |
| 115 | "optional": true | |
| 116 | } | |
| 117 | } | |
| 118 | }, | |
| 119 | "node_modules/bare-buffer": { | |
| 120 | "version": "3.7.1", | |
| 121 | "resolved": "https://registry.npmjs.org/bare-buffer/-/bare-buffer-3.7.1.tgz", | |
| 122 | "integrity": "sha512-cIjZnSO+y89ykVX9x96OVnA6tGORBn7vGJ/e3PCbBHMEyfMNG/ixzOS0lLa6saMlWcs69bSKjxFyDwjK152OMg==", | |
| 123 | "license": "Apache-2.0", | |
| 124 | "peer": true, | |
| 125 | "engines": { | |
| 126 | "bare": ">=1.20.0" | |
| 127 | } | |
| 128 | }, | |
| 129 | "node_modules/bare-bundle": { | |
| 130 | "version": "1.11.0", | |
| 131 | "resolved": "https://registry.npmjs.org/bare-bundle/-/bare-bundle-1.11.0.tgz", | |
| 132 | "integrity": "sha512-msaGQLaojz+EszDhf0qvCTmVWgJFSqbC5bUmEb9AKyVeglmJpx1EbCGqQTiXycCV7oA++MYqTagh/YdIZ//bmQ==", | |
| 133 | "dev": true, | |
| 134 | "license": "Apache-2.0", | |
| 135 | "peerDependencies": { | |
| 136 | "bare-buffer": "*", | |
| 137 | "bare-url": "*" | |
| 138 | }, | |
| 139 | "peerDependenciesMeta": { | |
| 140 | "bare-buffer": { | |
| 141 | "optional": true | |
| 142 | }, | |
| 143 | "bare-url": { | |
| 144 | "optional": true | |
| 145 | } | |
| 146 | } | |
| 147 | }, | |
| 148 | "node_modules/bare-channel": { | |
| 149 | "version": "5.3.0", | |
| 150 | "resolved": "https://registry.npmjs.org/bare-channel/-/bare-channel-5.3.0.tgz", | |
| 151 | "integrity": "sha512-W42Pkl/IjfkIVObQnixidRThST6ZcqY0u6AMTLb2+Jc/enBVsXPxzmyhEDoQjNNYi4WBGkOG7YHR4X46Ah9xfA==", | |
| 152 | "dev": true, | |
| 153 | "license": "Apache-2.0", | |
| 154 | "dependencies": { | |
| 155 | "bare-events": "^2.0.0", | |
| 156 | "bare-stream": "^2.7.0", | |
| 157 | "bare-structured-clone": "^2.0.0" | |
| 158 | }, | |
| 159 | "engines": { | |
| 160 | "bare": ">=1.7.0" | |
| 161 | } | |
| 162 | }, | |
| 163 | "node_modules/bare-cov": { | |
| 164 | "version": "1.2.3", | |
| 165 | "resolved": "https://registry.npmjs.org/bare-cov/-/bare-cov-1.2.3.tgz", | |
| 166 | "integrity": "sha512-M9XAEUxk3KKMMD2g8WwbrR0grc25RhkS95XnW6+PksSQdN1C43gYSOa0fQeun5Vo6rvTv501FEYyERKA43EzWg==", | |
| 167 | "dev": true, | |
| 168 | "license": "Apache-2.0", | |
| 169 | "dependencies": { | |
| 170 | "bare-fs": "^4.8.1", | |
| 171 | "bare-inspector": "^6.1.0", | |
| 172 | "bare-path": "^3.1.2", | |
| 173 | "bare-process": "^4.5.1", | |
| 174 | "bare-url": "^2.5.4", | |
| 175 | "bare-v8-to-istanbul": "^1.0.4", | |
| 176 | "picomatch": "^4.0.7", | |
| 177 | "which-runtime": "^1.4.0" | |
| 178 | } | |
| 179 | }, | |
| 180 | "node_modules/bare-crypto": { | |
| 181 | "version": "1.15.4", | |
| 182 | "resolved": "https://registry.npmjs.org/bare-crypto/-/bare-crypto-1.15.4.tgz", | |
| 183 | "integrity": "sha512-4luuiLnxIJvM7ZyyW6pXbaaGoQDZcIkfcVZrPzJ3oIpdi2UIP37dROmzBWqI2lnrzfKoQlKWM8ryHmyG2svViw==", | |
| 184 | "dev": true, | |
| 185 | "license": "Apache-2.0", | |
| 186 | "dependencies": { | |
| 187 | "bare-assert": "^1.2.0", | |
| 188 | "bare-stream": "^2.6.3" | |
| 189 | }, | |
| 190 | "peerDependencies": { | |
| 191 | "bare-buffer": "*" | |
| 192 | }, | |
| 193 | "peerDependenciesMeta": { | |
| 194 | "bare-buffer": { | |
| 195 | "optional": true | |
| 196 | } | |
| 197 | } | |
| 198 | }, | |
| 199 | "node_modules/bare-crypto/node_modules/bare-assert": { | |
| 200 | "version": "1.2.0", | |
| 201 | "resolved": "https://registry.npmjs.org/bare-assert/-/bare-assert-1.2.0.tgz", | |
| 202 | "integrity": "sha512-c6uvgvTJBspTDxtVnPgrBKmLgcpW3Fp72NVKDLg6oT4QjQbhGtvrkHMhGYMK1sh4vjBHOBmuUalyt9hSzV37fQ==", | |
| 203 | "dev": true, | |
| 204 | "license": "Apache-2.0", | |
| 205 | "dependencies": { | |
| 206 | "bare-inspect": "^3.1.2" | |
| 207 | } | |
| 208 | }, | |
| 209 | "node_modules/bare-debug-log": { | |
| 210 | "version": "2.0.0", | |
| 211 | "resolved": "https://registry.npmjs.org/bare-debug-log/-/bare-debug-log-2.0.0.tgz", | |
| 212 | "integrity": "sha512-Vi42PkMQsNV9PUpx2Gl1hikshx5O9FzMJ6o9Nnopseg7qLBBK7Nl31d0RHcfwLEAfmcPApytpc0ZFfq68u22FQ==", | |
| 213 | "dev": true, | |
| 214 | "license": "Apache-2.0", | |
| 215 | "dependencies": { | |
| 216 | "bare-os": "^3.0.1" | |
| 217 | } | |
| 218 | }, | |
| 219 | "node_modules/bare-dns": { | |
| 220 | "version": "2.2.1", | |
| 221 | "resolved": "https://registry.npmjs.org/bare-dns/-/bare-dns-2.2.1.tgz", | |
| 222 | "integrity": "sha512-76kta7f4YMiXwhdlK1q8AFnVvSlZ5yv4FL4AH83KoTRErgj0Ttm6Jo9993+gWEWQfl7VZTHtihPozstlknXszw==", | |
| 223 | "license": "Apache-2.0", | |
| 224 | "engines": { | |
| 225 | "bare": ">=1.7.0" | |
| 226 | }, | |
| 227 | "peerDependencies": { | |
| 228 | "bare-buffer": "*" | |
| 229 | }, | |
| 230 | "peerDependenciesMeta": { | |
| 231 | "bare-buffer": { | |
| 232 | "optional": true | |
| 233 | } | |
| 234 | } | |
| 235 | }, | |
| 236 | "node_modules/bare-encoding": { | |
| 237 | "version": "1.0.3", | |
| 238 | "resolved": "https://registry.npmjs.org/bare-encoding/-/bare-encoding-1.0.3.tgz", | |
| 239 | "integrity": "sha512-Kqf+t/azs13lUeyK4Tb7ha4wdLRXKWCXQ8w1rVmt7KtoPCPdHD/Xwt7LBIsCSwwGglrcmblo5VOLa5avkJqULA==", | |
| 240 | "dev": true, | |
| 241 | "license": "Apache-2.0", | |
| 242 | "peerDependencies": { | |
| 243 | "bare-buffer": "*" | |
| 244 | }, | |
| 245 | "peerDependenciesMeta": { | |
| 246 | "bare-buffer": { | |
| 247 | "optional": true | |
| 248 | } | |
| 249 | } | |
| 250 | }, | |
| 251 | "node_modules/bare-env": { | |
| 252 | "version": "3.0.1", | |
| 253 | "resolved": "https://registry.npmjs.org/bare-env/-/bare-env-3.0.1.tgz", | |
| 254 | "integrity": "sha512-BdoLvnzaWR0YyyJreEx4zG2Od0AC/s9JSZ+EXyMZKunpn8zEgR/dGv37hdFUaY1bjDkcRKvcKkFyJIwlJ0CaYA==", | |
| 255 | "license": "Apache-2.0", | |
| 256 | "dependencies": { | |
| 257 | "bare-os": "^3.0.1" | |
| 258 | } | |
| 259 | }, | |
| 260 | "node_modules/bare-events": { | |
| 261 | "version": "2.9.2", | |
| 262 | "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.2.tgz", | |
| 263 | "integrity": "sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA==", | |
| 264 | "license": "Apache-2.0", | |
| 265 | "peerDependencies": { | |
| 266 | "bare-abort-controller": "*" | |
| 267 | }, | |
| 268 | "peerDependenciesMeta": { | |
| 269 | "bare-abort-controller": { | |
| 270 | "optional": true | |
| 271 | } | |
| 272 | } | |
| 273 | }, | |
| 274 | "node_modules/bare-format": { | |
| 275 | "version": "1.0.2", | |
| 276 | "resolved": "https://registry.npmjs.org/bare-format/-/bare-format-1.0.2.tgz", | |
| 277 | "integrity": "sha512-GswdhnOnP9QtwRbrf4wLApw5widkaLMsLe2XOs35fQD2YfEN1ApoGka+cZ7PfvzxMgfYXmMhj/2OGlVn5/Dxgw==", | |
| 278 | "dev": true, | |
| 279 | "license": "Apache-2.0", | |
| 280 | "dependencies": { | |
| 281 | "bare-inspect": "^3.0.0" | |
| 282 | } | |
| 283 | }, | |
| 284 | "node_modules/bare-fs": { | |
| 285 | "version": "4.8.2", | |
| 286 | "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.8.2.tgz", | |
| 287 | "integrity": "sha512-+ZI68KHMUvosXfKbg/UOHK0tbCdRnegbvPEdEcZ3Nd6TetieQsJPRXBRXPdLyy8+3VSEbPXtsumTpEtt78xv9w==", | |
| 288 | "license": "Apache-2.0", | |
| 289 | "dependencies": { | |
| 290 | "bare-events": "^2.5.4", | |
| 291 | "bare-path": "^3.0.0", | |
| 292 | "bare-stream": "^2.6.4", | |
| 293 | "bare-url": "^2.2.2", | |
| 294 | "fast-fifo": "^1.3.2" | |
| 295 | }, | |
| 296 | "engines": { | |
| 297 | "bare": ">=1.28.0" | |
| 298 | }, | |
| 299 | "peerDependencies": { | |
| 300 | "bare-buffer": "*" | |
| 301 | }, | |
| 302 | "peerDependenciesMeta": { | |
| 303 | "bare-buffer": { | |
| 304 | "optional": true | |
| 305 | } | |
| 306 | } | |
| 307 | }, | |
| 308 | "node_modules/bare-hrtime": { | |
| 309 | "version": "2.1.2", | |
| 310 | "resolved": "https://registry.npmjs.org/bare-hrtime/-/bare-hrtime-2.1.2.tgz", | |
| 311 | "integrity": "sha512-ePu0axonbewvuUv9TFqjfvnZTaw+mL4JNx1q79dw8T3DIQEjqHs+pXyj92ghepa8K14KLtX3GdUuAVB+faaGDw==", | |
| 312 | "license": "Apache-2.0" | |
| 313 | }, | |
| 314 | "node_modules/bare-http-parser": { | |
| 315 | "version": "2.1.4", | |
| 316 | "resolved": "https://registry.npmjs.org/bare-http-parser/-/bare-http-parser-2.1.4.tgz", | |
| 317 | "integrity": "sha512-6CRjxqMdrEoKKBCS6FbdZUuVsRtyqq18BUae9l9N5okSV75S9lUAF9f5aFSKTNybBS/hcnlxFNocdpXbd2Ohaw==", | |
| 318 | "license": "Apache-2.0" | |
| 319 | }, | |
| 320 | "node_modules/bare-http1": { | |
| 321 | "version": "4.6.2", | |
| 322 | "resolved": "https://registry.npmjs.org/bare-http1/-/bare-http1-4.6.2.tgz", | |
| 323 | "integrity": "sha512-fnvBPNUH6KfdcEG7sKKKtvc3/9BEn3vkmJPgdtSLqGl6i2J9Csnl14mVv78ODPn8p3Zu2ZfmlG5XQzQQ45fwLw==", | |
| 324 | "license": "Apache-2.0", | |
| 325 | "dependencies": { | |
| 326 | "bare-events": "^2.6.0", | |
| 327 | "bare-hrtime": "^2.1.1", | |
| 328 | "bare-http-parser": "^2.1.0", | |
| 329 | "bare-stream": "^2.10.0", | |
| 330 | "bare-tcp": "^2.2.0" | |
| 331 | }, | |
| 332 | "peerDependencies": { | |
| 333 | "bare-buffer": "*", | |
| 334 | "bare-url": "*" | |
| 335 | }, | |
| 336 | "peerDependenciesMeta": { | |
| 337 | "bare-buffer": { | |
| 338 | "optional": true | |
| 339 | }, | |
| 340 | "bare-url": { | |
| 341 | "optional": true | |
| 342 | } | |
| 343 | } | |
| 344 | }, | |
| 345 | "node_modules/bare-https": { | |
| 346 | "version": "3.1.0", | |
| 347 | "resolved": "https://registry.npmjs.org/bare-https/-/bare-https-3.1.0.tgz", | |
| 348 | "integrity": "sha512-HNAS0q7CBAXGDFRy/xaYJEsAaVcvyDRXKU1b/KxS/zdcfBWsQVB0TntSzz3IlqZ5ZWHiaOOrMYAO/oIDgpTLkQ==", | |
| 349 | "dev": true, | |
| 350 | "license": "Apache-2.0", | |
| 351 | "dependencies": { | |
| 352 | "bare-http1": "^4.4.0", | |
| 353 | "bare-tcp": "^2.2.0", | |
| 354 | "bare-tls": "^3.0.0" | |
| 355 | } | |
| 356 | }, | |
| 357 | "node_modules/bare-inspect": { | |
| 358 | "version": "3.1.10", | |
| 359 | "resolved": "https://registry.npmjs.org/bare-inspect/-/bare-inspect-3.1.10.tgz", | |
| 360 | "integrity": "sha512-Qu01XZNTIT2/bS9k7c6A3OXuAzBnWwDCejGri76BUltdFqVe6Et/IxVOSSbcDpreSSWwqQ5pAu/bxFE6hPDWRQ==", | |
| 361 | "dev": true, | |
| 362 | "license": "Apache-2.0", | |
| 363 | "dependencies": { | |
| 364 | "bare-ansi-escapes": "^2.1.0", | |
| 365 | "bare-type": "^1.0.0" | |
| 366 | }, | |
| 367 | "engines": { | |
| 368 | "bare": ">=1.18.0" | |
| 369 | } | |
| 370 | }, | |
| 371 | "node_modules/bare-inspector": { | |
| 372 | "version": "6.1.0", | |
| 373 | "resolved": "https://registry.npmjs.org/bare-inspector/-/bare-inspector-6.1.0.tgz", | |
| 374 | "integrity": "sha512-PRxmZ4gF+K3TLzGubgRFvzdECybTCSKackgNsAdd4e7SdvICxMkGj+p5iX7bSKYSmgDnxgCR+2Z6UXmWykKhvw==", | |
| 375 | "dev": true, | |
| 376 | "license": "Apache-2.0", | |
| 377 | "dependencies": { | |
| 378 | "bare-events": "^2.1.0", | |
| 379 | "bare-http1": "^4.0.0", | |
| 380 | "bare-stream": "^2.0.0", | |
| 381 | "bare-url": "^2.0.0", | |
| 382 | "bare-ws": "^3.0.0" | |
| 383 | }, | |
| 384 | "engines": { | |
| 385 | "bare": ">=1.29.0" | |
| 386 | }, | |
| 387 | "peerDependencies": { | |
| 388 | "bare-tcp": "*" | |
| 389 | }, | |
| 390 | "peerDependenciesMeta": { | |
| 391 | "bare-tcp": { | |
| 392 | "optional": true | |
| 393 | } | |
| 394 | } | |
| 395 | }, | |
| 396 | "node_modules/bare-module": { | |
| 397 | "version": "6.4.0", | |
| 398 | "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-6.4.0.tgz", | |
| 399 | "integrity": "sha512-Yn4V5g5EqGQL4LYUOmt7fjKzj2JPWyJOqE3lPoeZwfUH5rk4CKUfZj6JhDwbzhBYCqqmUgjgQ5aY8cihAPILLA==", | |
| 400 | "dev": true, | |
| 401 | "license": "Apache-2.0", | |
| 402 | "dependencies": { | |
| 403 | "bare-bundle": "^1.3.0", | |
| 404 | "bare-module-lexer": "^1.0.0", | |
| 405 | "bare-module-resolve": "^1.8.0", | |
| 406 | "bare-path": "^3.0.0", | |
| 407 | "bare-type-stripper": "^0.1.2", | |
| 408 | "bare-url": "^2.0.1" | |
| 409 | }, | |
| 410 | "engines": { | |
| 411 | "bare": ">=1.29.4" | |
| 412 | }, | |
| 413 | "peerDependencies": { | |
| 414 | "bare-buffer": "*" | |
| 415 | }, | |
| 416 | "peerDependenciesMeta": { | |
| 417 | "bare-buffer": { | |
| 418 | "optional": true | |
| 419 | } | |
| 420 | } | |
| 421 | }, | |
| 422 | "node_modules/bare-module-lexer": { | |
| 423 | "version": "1.7.0", | |
| 424 | "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.7.0.tgz", | |
| 425 | "integrity": "sha512-LD5eiVhDyiMRfMtxK3E+0SeL95nkLNl37YUccXWEaErmfkJi596OECtUoH3X+YPomthwW2oQEch9c7aOOJ4ePA==", | |
| 426 | "dev": true, | |
| 427 | "license": "Apache-2.0", | |
| 428 | "dependencies": { | |
| 429 | "require-addon": "^1.0.2" | |
| 430 | }, | |
| 431 | "engines": { | |
| 432 | "bare": ">=1.0.0", | |
| 433 | "node": "^22.21.0 || >=24.9.0" | |
| 434 | }, | |
| 435 | "peerDependencies": { | |
| 436 | "bare-buffer": "*" | |
| 437 | }, | |
| 438 | "peerDependenciesMeta": { | |
| 439 | "bare-buffer": { | |
| 440 | "optional": true | |
| 441 | } | |
| 442 | } | |
| 443 | }, | |
| 444 | "node_modules/bare-module-resolve": { | |
| 445 | "version": "1.12.5", | |
| 446 | "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.12.5.tgz", | |
| 447 | "integrity": "sha512-VOncxVvVk8SQVw9vhcBnoTJD/74aR5DgdRPCm0gQ7uB5MsWpBJnoCeJrwEHKiz09O83ndf3NTjsz3LEuFxAq5A==", | |
| 448 | "dev": true, | |
| 449 | "license": "Apache-2.0", | |
| 450 | "dependencies": { | |
| 451 | "bare-semver": "^1.0.0" | |
| 452 | }, | |
| 453 | "peerDependencies": { | |
| 454 | "bare-url": "*" | |
| 455 | }, | |
| 456 | "peerDependenciesMeta": { | |
| 457 | "bare-url": { | |
| 458 | "optional": true | |
| 459 | } | |
| 460 | } | |
| 461 | }, | |
| 462 | "node_modules/bare-net": { | |
| 463 | "version": "2.3.3", | |
| 464 | "resolved": "https://registry.npmjs.org/bare-net/-/bare-net-2.3.3.tgz", | |
| 465 | "integrity": "sha512-q1noXFJKn+eNi6vXYv2Y+5FTnn+o7qpli4m2lUZTdK8cBjVs2zGaykuzTUIa29v70eOsQI9OAIyYwN3ODHtFaQ==", | |
| 466 | "license": "Apache-2.0", | |
| 467 | "dependencies": { | |
| 468 | "bare-events": "^2.2.2", | |
| 469 | "bare-pipe": "^4.0.0", | |
| 470 | "bare-stream": "^2.0.0", | |
| 471 | "bare-tcp": "^2.0.0" | |
| 472 | } | |
| 473 | }, | |
| 474 | "node_modules/bare-os": { | |
| 475 | "version": "3.9.3", | |
| 476 | "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.3.tgz", | |
| 477 | "integrity": "sha512-fF4Q7QsyKVF5Rj0qvI8BgUNjqzC2JvQlpTaPLjVJVxYVUX5Zr9un+y3w1HmA4nNKdFmRBT8z/WmrjvXzXVerKQ==", | |
| 478 | "license": "Apache-2.0", | |
| 479 | "engines": { | |
| 480 | "bare": ">=1.14.0" | |
| 481 | } | |
| 482 | }, | |
| 483 | "node_modules/bare-path": { | |
| 484 | "version": "3.1.2", | |
| 485 | "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.2.tgz", | |
| 486 | "integrity": "sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw==", | |
| 487 | "license": "Apache-2.0" | |
| 488 | }, | |
| 489 | "node_modules/bare-pipe": { | |
| 490 | "version": "4.3.1", | |
| 491 | "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-4.3.1.tgz", | |
| 492 | "integrity": "sha512-3P4MYTgOys1Bbz5dgWzwfroNOOl8x1zWJHTHVlwsojThhV/uJPRf+qFrYYBOnI0vQiJJLJtHlw8a4Osj/kcsJQ==", | |
| 493 | "license": "Apache-2.0", | |
| 494 | "dependencies": { | |
| 495 | "bare-events": "^2.5.4", | |
| 496 | "bare-stream": "^2.6.4" | |
| 497 | }, | |
| 498 | "engines": { | |
| 499 | "bare": ">=1.16.0" | |
| 500 | }, | |
| 501 | "peerDependencies": { | |
| 502 | "bare-buffer": "*" | |
| 503 | }, | |
| 504 | "peerDependenciesMeta": { | |
| 505 | "bare-buffer": { | |
| 506 | "optional": true | |
| 507 | } | |
| 508 | } | |
| 509 | }, | |
| 510 | "node_modules/bare-posix": { | |
| 511 | "version": "1.0.1", | |
| 512 | "resolved": "https://registry.npmjs.org/bare-posix/-/bare-posix-1.0.1.tgz", | |
| 513 | "integrity": "sha512-b4quA8dyRVvX0aFIAIiev5zFATHwIUGr42Gmt+CqiBNg/bdsNkrj4bbkeotMOMiljJS4DCME5kywJO/TFwKo1A==", | |
| 514 | "license": "Apache-2.0" | |
| 515 | }, | |
| 516 | "node_modules/bare-process": { | |
| 517 | "version": "4.5.1", | |
| 518 | "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.5.1.tgz", | |
| 519 | "integrity": "sha512-CaAvy1trputD49mtwfJ6G75vydhnirLrW/F3Sznp4H556e1uZn8YMo9ELicBTrGYy7RBNUgPl9bpB/ERzRCiDw==", | |
| 520 | "license": "Apache-2.0", | |
| 521 | "dependencies": { | |
| 522 | "bare-abort": "^2.0.13", | |
| 523 | "bare-env": "^3.0.0", | |
| 524 | "bare-events": "^2.3.1", | |
| 525 | "bare-hrtime": "^2.0.0", | |
| 526 | "bare-os": "^3.7.1", | |
| 527 | "bare-posix": "^1.0.1", | |
| 528 | "bare-signals": "^5.0.0", | |
| 529 | "bare-stdio": "^1.0.1" | |
| 530 | } | |
| 531 | }, | |
| 532 | "node_modules/bare-semver": { | |
| 533 | "version": "1.1.0", | |
| 534 | "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.1.0.tgz", | |
| 535 | "integrity": "sha512-1Hw5qJ7hXdVt3uPUqjeFTuxyvBUJauvz5A1I2jk8gzjZMHp04n//6nV9MDbG9CMw78JHY2lGV0w6s//LrASm2w==", | |
| 536 | "dev": true, | |
| 537 | "license": "Apache-2.0" | |
| 538 | }, | |
| 539 | "node_modules/bare-signals": { | |
| 540 | "version": "5.0.0", | |
| 541 | "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-5.0.0.tgz", | |
| 542 | "integrity": "sha512-8Gn8bBFUh2AUCJ9wWWFjSGWIo1HIUSIQnXRJGSm/f7GCDMqsuJhRmR1dT+HtDaDBkeu2l8Koxt2JLurfJ5yHVw==", | |
| 543 | "license": "Apache-2.0", | |
| 544 | "dependencies": { | |
| 545 | "bare-events": "^2.5.3" | |
| 546 | }, | |
| 547 | "engines": { | |
| 548 | "bare": ">=1.7.0" | |
| 549 | } | |
| 550 | }, | |
| 551 | "node_modules/bare-stdio": { | |
| 552 | "version": "1.0.3", | |
| 553 | "resolved": "https://registry.npmjs.org/bare-stdio/-/bare-stdio-1.0.3.tgz", | |
| 554 | "integrity": "sha512-8BRMx7RWMWCbBmKhyHgBco62J+Pgss7+EPI21L3R9+w0UpwDYWUUcbE0YTOesGyt7M6N7VtoshYbzwrP0pI52Q==", | |
| 555 | "license": "Apache-2.0", | |
| 556 | "dependencies": { | |
| 557 | "bare-fs": "^4.5.2", | |
| 558 | "bare-pipe": "^4.1.5", | |
| 559 | "bare-tty": "^5.0.3" | |
| 560 | } | |
| 561 | }, | |
| 562 | "node_modules/bare-stream": { | |
| 563 | "version": "2.13.4", | |
| 564 | "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.4.tgz", | |
| 565 | "integrity": "sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA==", | |
| 566 | "license": "Apache-2.0", | |
| 567 | "dependencies": { | |
| 568 | "b4a": "^1.8.1", | |
| 569 | "streamx": "^2.25.0", | |
| 570 | "teex": "^1.0.1" | |
| 571 | }, | |
| 572 | "peerDependencies": { | |
| 573 | "bare-abort-controller": "*", | |
| 574 | "bare-buffer": "*", | |
| 575 | "bare-events": "*" | |
| 576 | }, | |
| 577 | "peerDependenciesMeta": { | |
| 578 | "bare-abort-controller": { | |
| 579 | "optional": true | |
| 580 | }, | |
| 581 | "bare-buffer": { | |
| 582 | "optional": true | |
| 583 | }, | |
| 584 | "bare-events": { | |
| 585 | "optional": true | |
| 586 | } | |
| 587 | } | |
| 588 | }, | |
| 589 | "node_modules/bare-structured-clone": { | |
| 590 | "version": "1.6.0", | |
| 591 | "resolved": "https://registry.npmjs.org/bare-structured-clone/-/bare-structured-clone-1.6.0.tgz", | |
| 592 | "integrity": "sha512-AZjEERyqF7kAuudlmgrweT2KwwWM0LsGG4Gx/bWyFwJrKU7E3wNG8c09z2DIrdw93p3vDtfOX8fyHOcXfy5m+g==", | |
| 593 | "license": "Apache-2.0", | |
| 594 | "dependencies": { | |
| 595 | "bare-buffer": "^3.6.0", | |
| 596 | "bare-type": "^1.1.0", | |
| 597 | "bare-url": "^2.4.0", | |
| 598 | "compact-encoding": "^3.0.1" | |
| 599 | }, | |
| 600 | "engines": { | |
| 601 | "bare": ">=1.2.0" | |
| 602 | } | |
| 603 | }, | |
| 604 | "node_modules/bare-stylize": { | |
| 605 | "version": "0.0.1", | |
| 606 | "resolved": "https://registry.npmjs.org/bare-stylize/-/bare-stylize-0.0.1.tgz", | |
| 607 | "integrity": "sha512-l3MjmIl476bWijYWf3RbE+osl4iuXSOMudzp0vAqzIK7gPgn/+G3oAxp8Oin9CFF911KBP0LO9kts8Ci8mGZaQ==", | |
| 608 | "dev": true, | |
| 609 | "license": "Apache-2.0", | |
| 610 | "dependencies": { | |
| 611 | "bare-ansi-escapes": "^2.2.3", | |
| 612 | "bare-process": "^4.2.1" | |
| 613 | } | |
| 614 | }, | |
| 615 | "node_modules/bare-subprocess": { | |
| 616 | "version": "6.1.0", | |
| 617 | "resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-6.1.0.tgz", | |
| 618 | "integrity": "sha512-8L6KtbmreDy4Fc1BdDqaDo9fg0nbedUmTSFQxYPV0uHIM2BBAX8+E0LyMDKgkk0I+mlKto80WYzOnIhT8VDdOg==", | |
| 619 | "license": "Apache-2.0", | |
| 620 | "dependencies": { | |
| 621 | "bare-env": "^3.0.0", | |
| 622 | "bare-events": "^2.5.4", | |
| 623 | "bare-os": "^3.0.1", | |
| 624 | "bare-pipe": "^4.2.0", | |
| 625 | "bare-structured-clone": "^1.5.2", | |
| 626 | "bare-tcp": "^2.4.1", | |
| 627 | "bare-url": "^2.2.2" | |
| 628 | }, | |
| 629 | "engines": { | |
| 630 | "bare": ">=1.7.0" | |
| 631 | }, | |
| 632 | "peerDependencies": { | |
| 633 | "bare-buffer": "*" | |
| 634 | }, | |
| 635 | "peerDependenciesMeta": { | |
| 636 | "bare-buffer": { | |
| 637 | "optional": true | |
| 638 | } | |
| 639 | } | |
| 640 | }, | |
| 641 | "node_modules/bare-tcp": { | |
| 642 | "version": "2.6.1", | |
| 643 | "resolved": "https://registry.npmjs.org/bare-tcp/-/bare-tcp-2.6.1.tgz", | |
| 644 | "integrity": "sha512-8f8UFP7O27gIGaVWJPysQ2am8LSD6YCuVSbnTbOrQjUD0RkWEZexvi2Q66P99MLxSephlyjoU0mLxWmozRJMnA==", | |
| 645 | "license": "Apache-2.0", | |
| 646 | "dependencies": { | |
| 647 | "bare-dns": "^2.0.4", | |
| 648 | "bare-events": "^2.5.4", | |
| 649 | "bare-stream": "^2.6.4" | |
| 650 | }, | |
| 651 | "engines": { | |
| 652 | "bare": ">=1.16.0" | |
| 653 | }, | |
| 654 | "peerDependencies": { | |
| 655 | "bare-pipe": "*" | |
| 656 | }, | |
| 657 | "peerDependenciesMeta": { | |
| 658 | "bare-pipe": { | |
| 659 | "optional": true | |
| 660 | } | |
| 661 | } | |
| 662 | }, | |
| 663 | "node_modules/bare-tls": { | |
| 664 | "version": "3.1.11", | |
| 665 | "resolved": "https://registry.npmjs.org/bare-tls/-/bare-tls-3.1.11.tgz", | |
| 666 | "integrity": "sha512-lCQMepLYPPmdunO4MtkVe6l619Kdrt47/0HDGOgJY6zVvEeFACZD1hkh1kRw6zJk2NQHLcnebggYQZ/z6J/cPg==", | |
| 667 | "dev": true, | |
| 668 | "license": "Apache-2.0", | |
| 669 | "dependencies": { | |
| 670 | "bare-net": "^2.0.1", | |
| 671 | "bare-stream": "^2.6.4" | |
| 672 | }, | |
| 673 | "engines": { | |
| 674 | "bare": ">=1.7.0" | |
| 675 | } | |
| 676 | }, | |
| 677 | "node_modules/bare-tty": { | |
| 678 | "version": "5.2.1", | |
| 679 | "resolved": "https://registry.npmjs.org/bare-tty/-/bare-tty-5.2.1.tgz", | |
| 680 | "integrity": "sha512-vH9ggdu6q+HilCKcYCfSzwuN2QaR4+gGP+JiYN5zKMhMI6tKeKnZMCuE/AJoF9lbSo0FriPdZoKA5bO2b0Mk3w==", | |
| 681 | "license": "Apache-2.0", | |
| 682 | "dependencies": { | |
| 683 | "bare-events": "^2.2.0", | |
| 684 | "bare-signals": "^5.0.0", | |
| 685 | "bare-stream": "^2.0.0" | |
| 686 | }, | |
| 687 | "engines": { | |
| 688 | "bare": ">=1.16.0" | |
| 689 | } | |
| 690 | }, | |
| 691 | "node_modules/bare-type": { | |
| 692 | "version": "1.1.1", | |
| 693 | "resolved": "https://registry.npmjs.org/bare-type/-/bare-type-1.1.1.tgz", | |
| 694 | "integrity": "sha512-5HwbjDbnYr+Lwu5I59IqwOFcRcVo4jxo408t42gKhKnikw0ojwyPXPlx58AQP4dR2VvGw57ppX/qxYCn60Wujw==", | |
| 695 | "license": "Apache-2.0", | |
| 696 | "engines": { | |
| 697 | "bare": ">=1.2.0" | |
| 698 | } | |
| 699 | }, | |
| 700 | "node_modules/bare-type-stripper": { | |
| 701 | "version": "0.1.7", | |
| 702 | "resolved": "https://registry.npmjs.org/bare-type-stripper/-/bare-type-stripper-0.1.7.tgz", | |
| 703 | "integrity": "sha512-kiYTY1PqJnCQmaGT4Q23gskKCTtxqinPdA0SKMO80rjyLMdZhkT+mALf+/UryvovV6ysXtYXGSNPZR4wFhCI/g==", | |
| 704 | "dev": true, | |
| 705 | "license": "Apache-2.0", | |
| 706 | "dependencies": { | |
| 707 | "require-addon": "^1.0.2" | |
| 708 | }, | |
| 709 | "engines": { | |
| 710 | "bare": ">=1.0.0", | |
| 711 | "node": "^22.21.0 || >=24.9.0" | |
| 712 | }, | |
| 713 | "peerDependencies": { | |
| 714 | "bare-buffer": "*" | |
| 715 | }, | |
| 716 | "peerDependenciesMeta": { | |
| 717 | "bare-buffer": { | |
| 718 | "optional": true | |
| 719 | } | |
| 720 | } | |
| 721 | }, | |
| 722 | "node_modules/bare-url": { | |
| 723 | "version": "2.5.4", | |
| 724 | "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.5.4.tgz", | |
| 725 | "integrity": "sha512-Gxa7UVWBr0/edU1b+TJhn/AZvMQUj9OGspvYsaTYQrAbZA4BOTZGL3LiZxvD+CeMlDH4juwD84+eTAp/bLYW5g==", | |
| 726 | "license": "Apache-2.0", | |
| 727 | "peer": true, | |
| 728 | "dependencies": { | |
| 729 | "bare-path": "^3.0.0" | |
| 730 | } | |
| 731 | }, | |
| 732 | "node_modules/bare-utils": { | |
| 733 | "version": "1.6.0", | |
| 734 | "resolved": "https://registry.npmjs.org/bare-utils/-/bare-utils-1.6.0.tgz", | |
| 735 | "integrity": "sha512-WhQEIkkAxkSnW7u1QgrI0AfNm5JpMruETXeYsb5qnkBJ0TTfNKygZmsh6rkoHBANaV+C/7Jed7bJP9OmEHG7rQ==", | |
| 736 | "dev": true, | |
| 737 | "license": "Apache-2.0", | |
| 738 | "dependencies": { | |
| 739 | "bare-debug-log": "^2.0.0", | |
| 740 | "bare-encoding": "^1.0.0", | |
| 741 | "bare-format": "^1.0.0", | |
| 742 | "bare-inspect": "^3.0.0", | |
| 743 | "bare-stylize": "^0.0.1", | |
| 744 | "bare-type": "^1.0.6" | |
| 745 | } | |
| 746 | }, | |
| 747 | "node_modules/bare-v8-to-istanbul": { | |
| 748 | "version": "1.0.4", | |
| 749 | "resolved": "https://registry.npmjs.org/bare-v8-to-istanbul/-/bare-v8-to-istanbul-1.0.4.tgz", | |
| 750 | "integrity": "sha512-aYdse9SdVep4NT18jyMehBShfZgvyQ36Tm+oha2nQIHGcxvdBk0xZLbcYsDPzCTqGdJ5SfXa3VvZUSWyoa3L4w==", | |
| 751 | "dev": true, | |
| 752 | "license": "Apache-2.0", | |
| 753 | "dependencies": { | |
| 754 | "bare-assert": "^1.2.0", | |
| 755 | "bare-fs": "^4.8.1", | |
| 756 | "bare-module": "^6.4.0", | |
| 757 | "bare-path": "^3.1.2", | |
| 758 | "bare-process": "^4.5.1", | |
| 759 | "bare-url": "^2.5.4", | |
| 760 | "bare-utils": "^1.6.0", | |
| 761 | "v8-to-istanbul": "^9.3.0", | |
| 762 | "which-runtime": "^1.4.0" | |
| 763 | } | |
| 764 | }, | |
| 765 | "node_modules/bare-v8-to-istanbul/node_modules/bare-assert": { | |
| 766 | "version": "1.2.0", | |
| 767 | "resolved": "https://registry.npmjs.org/bare-assert/-/bare-assert-1.2.0.tgz", | |
| 768 | "integrity": "sha512-c6uvgvTJBspTDxtVnPgrBKmLgcpW3Fp72NVKDLg6oT4QjQbhGtvrkHMhGYMK1sh4vjBHOBmuUalyt9hSzV37fQ==", | |
| 769 | "dev": true, | |
| 770 | "license": "Apache-2.0", | |
| 771 | "dependencies": { | |
| 772 | "bare-inspect": "^3.1.2" | |
| 773 | } | |
| 774 | }, | |
| 775 | "node_modules/bare-ws": { | |
| 776 | "version": "3.2.0", | |
| 777 | "resolved": "https://registry.npmjs.org/bare-ws/-/bare-ws-3.2.0.tgz", | |
| 778 | "integrity": "sha512-9PPJX5JrhuObWZGyhYCrQ1DbhjY1BLVALkZF56r0SYnfyN18ok84yUETcQ377aC2W6w8IqBewjQ1GlovtiXA1Q==", | |
| 779 | "dev": true, | |
| 780 | "license": "Apache-2.0", | |
| 781 | "dependencies": { | |
| 782 | "bare-crypto": "^1.2.0", | |
| 783 | "bare-events": "^2.3.1", | |
| 784 | "bare-http1": "^4.0.0", | |
| 785 | "bare-https": "^3.0.0", | |
| 786 | "bare-stream": "^2.1.2" | |
| 787 | }, | |
| 788 | "peerDependencies": { | |
| 789 | "bare-buffer": "*", | |
| 790 | "bare-url": "*" | |
| 791 | }, | |
| 792 | "peerDependenciesMeta": { | |
| 793 | "bare-buffer": { | |
| 794 | "optional": true | |
| 795 | }, | |
| 796 | "bare-url": { | |
| 797 | "optional": true | |
| 798 | } | |
| 799 | } | |
| 800 | }, | |
| 801 | "node_modules/brittle": { | |
| 802 | "version": "4.1.1", | |
| 803 | "resolved": "https://registry.npmjs.org/brittle/-/brittle-4.1.1.tgz", | |
| 804 | "integrity": "sha512-FHzlSZ5KqB+2uXN1GYboQDzUkR+Z1n6MOXCnrSal5t41IJ9TM/EB+zCyIaOrEYgBpToRQn6U6NAqTYe45CqE5g==", | |
| 805 | "dev": true, | |
| 806 | "license": "Apache-2.0", | |
| 807 | "dependencies": { | |
| 808 | "b4a": "^1.8.0", | |
| 809 | "bare-assert": "^1.2.0", | |
| 810 | "bare-buffer": "^3.6.0", | |
| 811 | "bare-channel": "^5.2.3", | |
| 812 | "bare-cov": "^1.2.1", | |
| 813 | "bare-fs": "^4.5.5", | |
| 814 | "bare-os": "^3.7.1", | |
| 815 | "bare-path": "^3.0.0", | |
| 816 | "bare-process": "^4.3.0", | |
| 817 | "bare-subprocess": "^6.1.0", | |
| 818 | "bare-url": "^2.3.2", | |
| 819 | "bare-utils": "^1.6.0", | |
| 820 | "error-stack-parser": "^2.1.4", | |
| 821 | "globbie": "^1.0.3", | |
| 822 | "paparam": "^1.10.0", | |
| 823 | "same-object": "^1.0.2", | |
| 824 | "streamx": "^2.25.0", | |
| 825 | "test-tmp": "^1.4.0", | |
| 826 | "tmatch": "^5.0.0", | |
| 827 | "which-runtime": "^1.3.2" | |
| 828 | }, | |
| 829 | "bin": { | |
| 830 | "brittle": "advise.js", | |
| 831 | "brittle-bare": "brittle-bare.js", | |
| 832 | "brittle-make-test": "make-test.js", | |
| 833 | "brittle-node": "brittle-node.js" | |
| 834 | } | |
| 835 | }, | |
| 836 | "node_modules/brittle/node_modules/bare-assert": { | |
| 837 | "version": "1.2.0", | |
| 838 | "resolved": "https://registry.npmjs.org/bare-assert/-/bare-assert-1.2.0.tgz", | |
| 839 | "integrity": "sha512-c6uvgvTJBspTDxtVnPgrBKmLgcpW3Fp72NVKDLg6oT4QjQbhGtvrkHMhGYMK1sh4vjBHOBmuUalyt9hSzV37fQ==", | |
| 840 | "dev": true, | |
| 841 | "license": "Apache-2.0", | |
| 842 | "dependencies": { | |
| 843 | "bare-inspect": "^3.1.2" | |
| 844 | } | |
| 845 | }, | |
| 846 | "node_modules/compact-encoding": { | |
| 847 | "version": "3.5.2", | |
| 848 | "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.5.2.tgz", | |
| 849 | "integrity": "sha512-rgGcWdfxyuLwJHMUXI0OrYGpJe3VN4RZyovbxWVlxPYIsUZutOTfP3shmDyDi/iaybwcxMsTJDDuxQa4xRG0RQ==", | |
| 850 | "license": "Apache-2.0", | |
| 851 | "dependencies": { | |
| 852 | "b4a": "^1.3.0" | |
| 853 | } | |
| 854 | }, | |
| 855 | "node_modules/convert-source-map": { | |
| 856 | "version": "2.0.0", | |
| 857 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", | |
| 858 | "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", | |
| 859 | "dev": true, | |
| 860 | "license": "MIT" | |
| 861 | }, | |
| 862 | "node_modules/error-stack-parser": { | |
| 863 | "version": "2.1.4", | |
| 864 | "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", | |
| 865 | "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", | |
| 866 | "dev": true, | |
| 867 | "license": "MIT", | |
| 868 | "dependencies": { | |
| 869 | "stackframe": "^1.3.4" | |
| 870 | } | |
| 871 | }, | |
| 872 | "node_modules/events-universal": { | |
| 873 | "version": "1.0.1", | |
| 874 | "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", | |
| 875 | "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", | |
| 876 | "license": "Apache-2.0", | |
| 877 | "dependencies": { | |
| 878 | "bare-events": "^2.7.0" | |
| 879 | } | |
| 880 | }, | |
| 881 | "node_modules/fast-fifo": { | |
| 882 | "version": "1.3.2", | |
| 883 | "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", | |
| 884 | "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", | |
| 885 | "license": "MIT" | |
| 886 | }, | |
| 887 | "node_modules/globbie": { | |
| 888 | "version": "1.0.6", | |
| 889 | "resolved": "https://registry.npmjs.org/globbie/-/globbie-1.0.6.tgz", | |
| 890 | "integrity": "sha512-GcxSSfWinZNZNW3+RsPBi2nW4jJcUJsOKiJvuXoeO3Y8pdd045NVPILCAoNCzYUsPw5XAUA/GXwRXF+ABcAeOQ==", | |
| 891 | "dev": true, | |
| 892 | "license": "Apache-2.0", | |
| 893 | "dependencies": { | |
| 894 | "bare-fs": "^4.7.4", | |
| 895 | "bare-path": "^3.1.1", | |
| 896 | "bare-process": "^4.5.1", | |
| 897 | "picomatch": "^4.0.5" | |
| 898 | } | |
| 899 | }, | |
| 900 | "node_modules/paparam": { | |
| 901 | "version": "1.13.0", | |
| 902 | "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.13.0.tgz", | |
| 903 | "integrity": "sha512-WV8vCnEBPKcSSEIDSaAetppO+C0+OUJ6gjO1BGbhvIp2jc8zfV9C/8NARjEGgnUo5DDwdNsGOrFTZKLFTTeB0A==", | |
| 904 | "dev": true, | |
| 905 | "license": "Apache-2.0" | |
| 906 | }, | |
| 907 | "node_modules/picomatch": { | |
| 908 | "version": "4.0.7", | |
| 909 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", | |
| 910 | "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", | |
| 911 | "dev": true, | |
| 912 | "license": "MIT", | |
| 913 | "engines": { | |
| 914 | "node": ">=12" | |
| 915 | }, | |
| 916 | "funding": { | |
| 917 | "url": "https://github.com/sponsors/jonschlinkert" | |
| 918 | } | |
| 919 | }, | |
| 920 | "node_modules/require-addon": { | |
| 921 | "version": "1.3.0", | |
| 922 | "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.3.0.tgz", | |
| 923 | "integrity": "sha512-j8pifaPNZI7ShKY3ihXZwF0qaEjua8zmlqPvDil0a8SBnyRvjCbAiEQuzO0UcoXH1sqU5U/ilXSjYd1W5NYwAA==", | |
| 924 | "dev": true, | |
| 925 | "license": "Apache-2.0", | |
| 926 | "dependencies": { | |
| 927 | "bare-addon-resolve": "^1.3.0" | |
| 928 | }, | |
| 929 | "engines": { | |
| 930 | "bare": ">=1.10.0" | |
| 931 | } | |
| 932 | }, | |
| 933 | "node_modules/same-object": { | |
| 934 | "version": "1.0.2", | |
| 935 | "resolved": "https://registry.npmjs.org/same-object/-/same-object-1.0.2.tgz", | |
| 936 | "integrity": "sha512-csHWhvUsLbIOHDM/nP+KHWM+BLPsIzWkFa8HbzaI0G7BqKXgx+7FJpKTGgLXyz5amfdY2OVBcmXTqYOMEk04og==", | |
| 937 | "dev": true, | |
| 938 | "license": "MIT" | |
| 939 | }, | |
| 940 | "node_modules/stackframe": { | |
| 941 | "version": "1.3.4", | |
| 942 | "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", | |
| 943 | "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", | |
| 944 | "dev": true, | |
| 945 | "license": "MIT" | |
| 946 | }, | |
| 947 | "node_modules/streamx": { | |
| 948 | "version": "2.28.1", | |
| 949 | "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.28.1.tgz", | |
| 950 | "integrity": "sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==", | |
| 951 | "license": "MIT", | |
| 952 | "dependencies": { | |
| 953 | "events-universal": "^1.0.0", | |
| 954 | "fast-fifo": "^1.3.2", | |
| 955 | "text-decoder": "^1.1.0" | |
| 956 | } | |
| 957 | }, | |
| 958 | "node_modules/teex": { | |
| 959 | "version": "1.0.1", | |
| 960 | "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", | |
| 961 | "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", | |
| 962 | "license": "MIT", | |
| 963 | "dependencies": { | |
| 964 | "streamx": "^2.12.5" | |
| 965 | } | |
| 966 | }, | |
| 967 | "node_modules/test-tmp": { | |
| 968 | "version": "1.4.0", | |
| 969 | "resolved": "https://registry.npmjs.org/test-tmp/-/test-tmp-1.4.0.tgz", | |
| 970 | "integrity": "sha512-GVggxGg+jXqP2Wbju50JVLo+9E+nIOPPyWqgr63EbOnNItIKu1cEbJpTWAJeflnyGqXOtcMI7ijHRp88GUkfDA==", | |
| 971 | "dev": true, | |
| 972 | "license": "MIT", | |
| 973 | "dependencies": { | |
| 974 | "bare-fs": "^4.0.1", | |
| 975 | "bare-os": "^3.3.0", | |
| 976 | "bare-path": "^3.0.0" | |
| 977 | } | |
| 978 | }, | |
| 979 | "node_modules/text-decoder": { | |
| 980 | "version": "1.2.7", | |
| 981 | "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", | |
| 982 | "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", | |
| 983 | "license": "Apache-2.0", | |
| 984 | "dependencies": { | |
| 985 | "b4a": "^1.6.4" | |
| 986 | } | |
| 987 | }, | |
| 988 | "node_modules/tmatch": { | |
| 989 | "version": "5.0.0", | |
| 990 | "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-5.0.0.tgz", | |
| 991 | "integrity": "sha512-Ib9OtBkpHn07tXP04SlN1SYRxFgTk6wSM2EBmjjxug4u5RXPRVLkdFJSS1PmrQidaSB8Lru9nRtViQBsbxzE5Q==", | |
| 992 | "dev": true, | |
| 993 | "license": "ISC", | |
| 994 | "engines": { | |
| 995 | "node": ">=8" | |
| 996 | } | |
| 997 | }, | |
| 998 | "node_modules/v8-to-istanbul": { | |
| 999 | "version": "9.3.0", | |
| 1000 | "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", | |
| 1001 | "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", | |
| 1002 | "dev": true, | |
| 1003 | "license": "ISC", | |
| 1004 | "dependencies": { | |
| 1005 | "@jridgewell/trace-mapping": "^0.3.12", | |
| 1006 | "@types/istanbul-lib-coverage": "^2.0.1", | |
| 1007 | "convert-source-map": "^2.0.0" | |
| 1008 | }, | |
| 1009 | "engines": { | |
| 1010 | "node": ">=10.12.0" | |
| 1011 | } | |
| 1012 | }, | |
| 1013 | "node_modules/which-runtime": { | |
| 1014 | "version": "1.4.0", | |
| 1015 | "resolved": "https://registry.npmjs.org/which-runtime/-/which-runtime-1.4.0.tgz", | |
| 1016 | "integrity": "sha512-0ugbP4CJW4e2D20jvEcC4973dCgIaHI4Rw1PT+26U9zEve7FyYdWAIwUnoeOYvoCfn+wXHoHTKb1KhkYlb60Pw==", | |
| 1017 | "dev": true, | |
| 1018 | "license": "Apache-2.0" | |
| 1019 | } | |
| 1020 | } | |
| 1021 | } |
| … | … | @@ -0,0 +1,51 @@ |
| 1 | { | |
| 2 | "name": "host-services", | |
| 3 | "version": "0.1.0", | |
| 4 | "description": "One page listing every service a host runs (pgh apps, systemd units, listening ports) with active / dormant state, plus the LAN's other devices and what they serve.", | |
| 5 | "type": "module", | |
| 6 | "main": "index.js", | |
| 7 | "bin": { | |
| 8 | "host-services": "index.js" | |
| 9 | }, | |
| 10 | "scripts": { | |
| 11 | "test": "brittle-bare test/*.test.js" | |
| 12 | }, | |
| 13 | "dependencies": { | |
| 14 | "bare-events": "2.9.2", | |
| 15 | "bare-fs": "4.8.2", | |
| 16 | "bare-http1": "4.6.2", | |
| 17 | "bare-net": "2.3.3", | |
| 18 | "bare-os": "3.9.3", | |
| 19 | "bare-path": "3.1.2", | |
| 20 | "bare-process": "4.5.1", | |
| 21 | "bare-subprocess": "6.1.0" | |
| 22 | }, | |
| 23 | "devDependencies": { | |
| 24 | "brittle": "4.1.1" | |
| 25 | }, | |
| 26 | "pgh": { | |
| 27 | "bin": "host-services", | |
| 28 | "entrypoint": "index.js", | |
| 29 | "type": "daemon", | |
| 30 | "runtime": "bare", | |
| 31 | "upgrade": "pgh://1dd36bdfa9cb7f7d84adbd07f017e7200f7f90a3a546cd0761fac2a1f8a13e86/host-services", | |
| 32 | "autostart": false, | |
| 33 | "depends": [ | |
| 34 | "pgh-sidecar" | |
| 35 | ], | |
| 36 | "defaults": { | |
| 37 | "env": { | |
| 38 | "HOST_SERVICES_PORT": "4060", | |
| 39 | "HOST_SERVICES_HOST": "0.0.0.0" | |
| 40 | } | |
| 41 | }, | |
| 42 | "service": { | |
| 43 | "requiresNetwork": true | |
| 44 | } | |
| 45 | }, | |
| 46 | "overrides": { | |
| 47 | "bare-type": "1.1.1", | |
| 48 | "bare-structured-clone": "1.6.0", | |
| 49 | "bare-assert": "1.2.0" | |
| 50 | } | |
| 51 | } |
| … | … | @@ -0,0 +1,87 @@ |
| 1 | :root { | |
| 2 | --bg: #f6f7f9; | |
| 3 | --card: #ffffff; | |
| 4 | --text: #1c2129; | |
| 5 | --muted: #667085; | |
| 6 | --line: #e3e6eb; | |
| 7 | --accent: #2f6fde; | |
| 8 | --active: #1f9d55; | |
| 9 | --degraded: #d97706; | |
| 10 | --failed: #d6453d; | |
| 11 | --dormant: #8a94a6; | |
| 12 | --chip: #eef1f5; | |
| 13 | } | |
| 14 | @media (prefers-color-scheme: dark) { | |
| 15 | :root { | |
| 16 | --bg: #12151a; | |
| 17 | --card: #1b2028; | |
| 18 | --text: #e6e9ee; | |
| 19 | --muted: #8d97a8; | |
| 20 | --line: #2a313c; | |
| 21 | --accent: #6c9cf0; | |
| 22 | --chip: #232a34; | |
| 23 | } | |
| 24 | } | |
| 25 | * { box-sizing: border-box; } | |
| 26 | body { | |
| 27 | margin: 0; | |
| 28 | background: var(--bg); | |
| 29 | color: var(--text); | |
| 30 | font: 14px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif; | |
| 31 | padding: 16px; | |
| 32 | max-width: 1200px; | |
| 33 | margin-inline: auto; | |
| 34 | } | |
| 35 | header { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: end; gap: 12px; margin-bottom: 12px; } | |
| 36 | h1 { margin: 0; font-size: 22px; } | |
| 37 | .sub { color: var(--muted); font-size: 13px; } | |
| 38 | .counts { display: flex; gap: 8px; flex-wrap: wrap; } | |
| 39 | .count { background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; display: flex; gap: 6px; align-items: center; } | |
| 40 | .count b { font-size: 16px; } | |
| 41 | .dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; } | |
| 42 | .dot.active { background: var(--active); } | |
| 43 | .dot.degraded { background: var(--degraded); } | |
| 44 | .dot.failed { background: var(--failed); } | |
| 45 | .dot.dormant { background: var(--dormant); } | |
| 46 | .errors { background: color-mix(in srgb, var(--failed) 12%, var(--card)); border: 1px solid var(--failed); border-radius: 8px; padding: 8px 12px; margin-bottom: 12px; } | |
| 47 | .tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 12px; } | |
| 48 | .tabs button { background: none; border: 0; border-bottom: 2px solid transparent; padding: 8px 12px; color: var(--muted); font: inherit; cursor: pointer; } | |
| 49 | .tabs button.on { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; } | |
| 50 | .toolbar { display: flex; flex-wrap: wrap; gap: 8px; justify-content: space-between; align-items: center; margin-bottom: 10px; } | |
| 51 | .chips { display: flex; gap: 6px; flex-wrap: wrap; } | |
| 52 | .chips button, button.primary { | |
| 53 | border: 1px solid var(--line); background: var(--card); color: var(--text); | |
| 54 | border-radius: 999px; padding: 5px 12px; font: inherit; cursor: pointer; | |
| 55 | } | |
| 56 | .chips button.on { background: var(--accent); border-color: var(--accent); color: #fff; } | |
| 57 | button.primary { background: var(--accent); border-color: var(--accent); color: #fff; border-radius: 8px; } | |
| 58 | button.primary:disabled { opacity: .6; cursor: default; } | |
| 59 | input[type=search] { flex: 1 1 220px; max-width: 360px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); color: var(--text); font: inherit; } | |
| 60 | .list { display: grid; gap: 8px; } | |
| 61 | .card { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; display: grid; gap: 4px; } | |
| 62 | .card.dormant { opacity: .72; } | |
| 63 | .row1 { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; } | |
| 64 | .name { font-weight: 600; font-size: 15px; } | |
| 65 | .badge { font-size: 11px; padding: 1px 7px; border-radius: 999px; background: var(--chip); color: var(--muted); } | |
| 66 | .state { font-size: 12px; font-weight: 600; display: inline-flex; gap: 5px; align-items: center; } | |
| 67 | .state.active { color: var(--active); } | |
| 68 | .state.degraded { color: var(--degraded); } | |
| 69 | .state.failed { color: var(--failed); } | |
| 70 | .state.dormant { color: var(--dormant); } | |
| 71 | .meta { color: var(--muted); font-size: 12.5px; display: flex; flex-wrap: wrap; gap: 4px 14px; } | |
| 72 | .ports { display: flex; flex-wrap: wrap; gap: 6px; } | |
| 73 | .port { border: 1px solid var(--line); border-radius: 6px; padding: 2px 8px; font-size: 12.5px; display: inline-flex; gap: 6px; align-items: center; max-width: 100%; } | |
| 74 | .port a { color: var(--accent); text-decoration: none; font-weight: 600; } | |
| 75 | .port a:hover { text-decoration: underline; } | |
| 76 | .port .t { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 260px; } | |
| 77 | .port.closed { border-style: dashed; color: var(--muted); } | |
| 78 | .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; } | |
| 79 | .system { margin-top: 16px; } | |
| 80 | .system summary { cursor: pointer; color: var(--muted); } | |
| 81 | .syslist { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 2px 16px; margin-top: 8px; font-size: 12.5px; } | |
| 82 | .syslist span { display: flex; gap: 6px; align-items: center; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } | |
| 83 | .empty { color: var(--muted); padding: 16px; text-align: center; } | |
| 84 | @media (max-width: 600px) { | |
| 85 | body { padding: 12px; } | |
| 86 | .port .t { max-width: 160px; } | |
| 87 | } |
| … | … | @@ -0,0 +1,195 @@ |
| 1 | // host-services page: polls /api/host and /api/lan and renders them. | |
| 2 | ||
| 3 | const $ = (id) => document.getElementById(id) | |
| 4 | const STATES = ['active', 'degraded', 'failed', 'dormant'] | |
| 5 | const STATE_LABEL = { active: 'Active', degraded: 'Degraded', failed: 'Failed', dormant: 'Dormant' } | |
| 6 | const KIND_LABEL = { pgh: 'pgh app', unit: 'systemd', 'user-unit': 'user unit', process: 'process', port: 'port' } | |
| 7 | const ORDER = { failed: 0, degraded: 1, active: 2, dormant: 3 } | |
| 8 | ||
| 9 | let host = null | |
| 10 | let lan = null | |
| 11 | let filter = 'all' | |
| 12 | let query = '' | |
| 13 | ||
| 14 | function esc (s) { | |
| 15 | return String(s == null ? '' : s).replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c]) | |
| 16 | } | |
| 17 | ||
| 18 | function ago (iso) { | |
| 19 | if (!iso) return '' | |
| 20 | const t = Date.parse(iso) | |
| 21 | if (isNaN(t)) return iso | |
| 22 | const s = Math.round((Date.now() - t) / 1000) | |
| 23 | if (s < 60) return s + 's ago' | |
| 24 | if (s < 3600) return Math.round(s / 60) + 'm ago' | |
| 25 | if (s < 86400) return Math.round(s / 3600) + 'h ago' | |
| 26 | return Math.round(s / 86400) + 'd ago' | |
| 27 | } | |
| 28 | ||
| 29 | // Where a browser on the LAN reaches a port of host `h`. | |
| 30 | function portUrl (h, p) { | |
| 31 | const tls = !p.http && (p.port === 443 || p.port === 8443 || p.port === 8920) | |
| 32 | return (tls ? 'https://' : 'http://') + h + (p.port === (tls ? 443 : 80) ? '' : ':' + p.port) + '/' | |
| 33 | } | |
| 34 | ||
| 35 | function portChip (p, hostname) { | |
| 36 | const label = p.label && p.label.name | |
| 37 | const title = p.http && p.http.title | |
| 38 | const what = [title, label && label !== title ? label : null].filter(Boolean).join(' · ') | |
| 39 | const status = p.http ? p.http.code : (p.banner ? 'tcp' : '') | |
| 40 | const reachable = p.scope !== 'local' | |
| 41 | const head = reachable && (p.http || p.open) | |
| 42 | ? '<a href="' + esc(portUrl(hostname, p)) + '" target="_blank" rel="noopener">:' + p.port + '</a>' | |
| 43 | : '<span class="mono">:' + p.port + '</span>' | |
| 44 | const notes = [ | |
| 45 | p.scope === 'local' ? 'localhost only' : null, | |
| 46 | p.scope === 'addr' ? p.addr : null, | |
| 47 | p.open === false ? 'not answering' : null, | |
| 48 | status ? String(status) : null | |
| 49 | ].filter(Boolean).join(' · ') | |
| 50 | return '<span class="port' + (p.open === false ? ' closed' : '') + '" title="' + esc([what, notes, p.banner].filter(Boolean).join('\n')) + '">' + | |
| 51 | head + (what ? '<span class="t">' + esc(what) + '</span>' : '') + | |
| 52 | (notes ? '<span class="t">' + esc(notes) + '</span>' : '') + '</span>' | |
| 53 | } | |
| 54 | ||
| 55 | function displayName (s) { | |
| 56 | return (s.label && s.label.name) || s.name | |
| 57 | } | |
| 58 | ||
| 59 | function matches (s) { | |
| 60 | if (filter === 'active' && s.state !== 'active') return false | |
| 61 | if (filter === 'dormant' && s.state !== 'dormant') return false | |
| 62 | if (filter === 'problems' && s.state !== 'degraded' && s.state !== 'failed') return false | |
| 63 | if (!query) return true | |
| 64 | const hay = [displayName(s), s.name, s.description, s.user, s.kind, (s.label && s.label.description), | |
| 65 | ...s.ports.map((p) => p.port + ' ' + ((p.http && p.http.title) || '') + ' ' + ((p.label && p.label.name) || ''))].join(' ').toLowerCase() | |
| 66 | return hay.includes(query) | |
| 67 | } | |
| 68 | ||
| 69 | function renderHost () { | |
| 70 | if (!host) return | |
| 71 | $('host').textContent = host.host | |
| 72 | document.title = host.host + ' · services' | |
| 73 | $('updated').textContent = 'updated ' + ago(host.at) | |
| 74 | const n = Object.fromEntries(STATES.map((k) => [k, 0])) | |
| 75 | for (const s of host.services) n[s.state]++ | |
| 76 | $('counts').innerHTML = STATES.map((k) => '<span class="count"><span class="dot ' + k + '"></span><b>' + n[k] + '</b> ' + STATE_LABEL[k] + '</span>').join('') | |
| 77 | ||
| 78 | const errs = host.errors || [] | |
| 79 | $('errors').hidden = errs.length === 0 | |
| 80 | $('errors').innerHTML = errs.map(esc).join('<br>') | |
| 81 | ||
| 82 | const hostname = location.hostname | |
| 83 | const list = host.services.filter(matches).sort((a, b) => | |
| 84 | (ORDER[a.state] - ORDER[b.state]) || displayName(a).localeCompare(displayName(b))) | |
| 85 | $('services').innerHTML = list.length | |
| 86 | ? list.map((s) => { | |
| 87 | const meta = [ | |
| 88 | s.description || (s.label && s.label.description), | |
| 89 | s.version ? 'v' + s.version : null, | |
| 90 | s.kind === 'pgh' ? 'autostart ' + (s.autostart ? 'on' : 'off') : null, | |
| 91 | s.enabled && s.kind !== 'pgh' ? s.enabled : null, | |
| 92 | s.user ? 'user ' + s.user : null, | |
| 93 | s.owner && s.owner.user ? 'user ' + s.owner.user : null, | |
| 94 | s.owner && s.owner.cmd ? s.owner.cmd : null, | |
| 95 | s.since ? (s.running ? 'up since ' : 'stopped ') + ago(s.since) : null, | |
| 96 | s.kind === 'pgh' && !s.running && s.lastExitCode != null ? 'last exit ' + s.lastExitCode : null, | |
| 97 | s.activeState && s.state !== 'active' && s.state !== 'dormant' ? s.activeState + '/' + s.subState : null | |
| 98 | ].filter(Boolean) | |
| 99 | return '<div class="card ' + s.state + '">' + | |
| 100 | '<div class="row1"><span class="state ' + s.state + '"><span class="dot ' + s.state + '"></span>' + STATE_LABEL[s.state] + '</span>' + | |
| 101 | '<span class="name">' + esc(displayName(s)) + '</span>' + | |
| 102 | (displayName(s) !== s.name ? '<span class="mono sub">' + esc(s.name) + '</span>' : '') + | |
| 103 | '<span class="badge">' + esc(KIND_LABEL[s.kind] || s.kind) + '</span></div>' + | |
| 104 | (meta.length ? '<div class="meta">' + meta.map((m) => '<span>' + esc(m) + '</span>').join('') + '</div>' : '') + | |
| 105 | (s.ports.length ? '<div class="ports">' + s.ports.map((p) => portChip(p, hostname)).join('') + '</div>' : '') + | |
| 106 | '</div>' | |
| 107 | }).join('') | |
| 108 | : '<div class="empty">Nothing matches.</div>' | |
| 109 | ||
| 110 | const sys = host.system || [] | |
| 111 | $('system-sum').textContent = 'Operating-system units (' + sys.length + ')' | |
| 112 | $('system').innerHTML = sys.sort((a, b) => a.name.localeCompare(b.name)).map((u) => { | |
| 113 | const st = u.state === 'active' ? 'active' : u.state === 'failed' ? 'failed' : 'dormant' | |
| 114 | return '<span title="' + esc(u.state + '/' + u.sub + ' · ' + u.enabled) + '"><span class="dot ' + st + '"></span>' + esc(u.name) + '</span>' | |
| 115 | }).join('') | |
| 116 | } | |
| 117 | ||
| 118 | function renderLan () { | |
| 119 | if (!lan) return | |
| 120 | const r = lan.result | |
| 121 | $('scan').disabled = lan.scanning | |
| 122 | $('scan').textContent = lan.scanning ? 'Scanning…' : 'Scan now' | |
| 123 | $('lan-meta').textContent = lan.scanning | |
| 124 | ? 'Scanning: ' + lan.progress | |
| 125 | : r ? r.hosts.length + ' devices on ' + r.subnets.map((s) => s + '.0/24').join(', ') + ' · ' + r.ports + ' ports checked · scanned ' + ago(r.at) + ' in ' + Math.round(r.durationMs / 1000) + 's' | |
| 126 | : 'No scan yet.' | |
| 127 | if (!r) { | |
| 128 | $('lan').innerHTML = '<div class="empty">' + (lan.scanning ? 'First scan running…' : 'No scan yet.') + '</div>' | |
| 129 | return | |
| 130 | } | |
| 131 | $('lan').innerHTML = r.hosts.map((h) => { | |
| 132 | const name = h.names[0] || h.ip | |
| 133 | const linkHost = h.names[0] || h.ip | |
| 134 | const ports = h.ports.map((p) => portChip({ ...p, scope: 'all', open: true }, linkHost)).join('') | |
| 135 | const mdns = h.mdns.map((m) => m.name + ' (' + m.type.replace(/^_|\._tcp$|\._udp$/g, '') + (m.port ? ':' + m.port : '') + ')') | |
| 136 | return '<div class="card">' + | |
| 137 | '<div class="row1"><span class="name">' + esc(name) + '</span>' + | |
| 138 | (name !== h.ip ? '<span class="mono sub">' + esc(h.ip) + '</span>' : '') + | |
| 139 | (h.self ? '<span class="badge">this host</span>' : '') + | |
| 140 | (h.ports.length ? '' : '<span class="badge">no open ports found</span>') + '</div>' + | |
| 141 | '<div class="meta">' + [h.mac ? '<span class="mono">' + esc(h.mac) + '</span>' : null, ...h.names.slice(1).map(esc)].filter(Boolean).map((m) => '<span>' + m + '</span>').join('') + '</div>' + | |
| 142 | (ports ? '<div class="ports">' + ports + '</div>' : '') + | |
| 143 | (mdns.length ? '<div class="meta"><span>mDNS: ' + esc(mdns.join(', ')) + '</span></div>' : '') + | |
| 144 | '</div>' | |
| 145 | }).join('') | |
| 146 | } | |
| 147 | ||
| 148 | async function loadHost () { | |
| 149 | try { | |
| 150 | const r = await fetch('/api/host') | |
| 151 | host = await r.json() | |
| 152 | renderHost() | |
| 153 | } catch (err) { | |
| 154 | $('errors').hidden = false | |
| 155 | $('errors').textContent = 'Could not load /api/host: ' + err.message | |
| 156 | } | |
| 157 | } | |
| 158 | ||
| 159 | async function loadLan () { | |
| 160 | try { | |
| 161 | lan = await (await fetch('/api/lan')).json() | |
| 162 | renderLan() | |
| 163 | } catch {} | |
| 164 | setTimeout(loadLan, lan && lan.scanning ? 3000 : 30000) | |
| 165 | } | |
| 166 | ||
| 167 | $('filters').addEventListener('click', (e) => { | |
| 168 | const f = e.target.dataset.f | |
| 169 | if (!f) return | |
| 170 | filter = f | |
| 171 | for (const b of $('filters').children) b.classList.toggle('on', b.dataset.f === f) | |
| 172 | renderHost() | |
| 173 | }) | |
| 174 | $('q').addEventListener('input', (e) => { | |
| 175 | query = e.target.value.trim().toLowerCase() | |
| 176 | renderHost() | |
| 177 | }) | |
| 178 | document.querySelector('.tabs').addEventListener('click', (e) => { | |
| 179 | const t = e.target.dataset.tab | |
| 180 | if (!t) return | |
| 181 | for (const b of document.querySelectorAll('.tabs button')) b.classList.toggle('on', b.dataset.tab === t) | |
| 182 | $('tab-services').hidden = t !== 'services' | |
| 183 | $('tab-lan').hidden = t !== 'lan' | |
| 184 | }) | |
| 185 | $('scan').addEventListener('click', async () => { | |
| 186 | await fetch('/api/lan/scan', { method: 'POST', headers: { 'x-host-services': '1' } }) | |
| 187 | lan = { ...(lan || {}), scanning: true, progress: 'starting' } | |
| 188 | renderLan() | |
| 189 | setTimeout(loadLan, 1500) | |
| 190 | }) | |
| 191 | ||
| 192 | loadHost() | |
| 193 | setInterval(loadHost, 20000) | |
| 194 | setInterval(renderHost, 10000) | |
| 195 | loadLan() |
| … | … | @@ -0,0 +1,52 @@ |
| 1 | <!doctype html> | |
| 2 | <html lang="en"> | |
| 3 | <head> | |
| 4 | <meta charset="utf-8"> | |
| 5 | <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| 6 | <title>Host services</title> | |
| 7 | <link rel="stylesheet" href="/app.css"> | |
| 8 | </head> | |
| 9 | <body> | |
| 10 | <header> | |
| 11 | <div class="title"> | |
| 12 | <h1 id="host">…</h1> | |
| 13 | <span class="sub" id="updated"></span> | |
| 14 | </div> | |
| 15 | <div class="counts" id="counts"></div> | |
| 16 | </header> | |
| 17 | ||
| 18 | <div id="errors" class="errors" hidden></div> | |
| 19 | ||
| 20 | <nav class="tabs"> | |
| 21 | <button data-tab="services" class="on">Services</button> | |
| 22 | <button data-tab="lan">Network</button> | |
| 23 | </nav> | |
| 24 | ||
| 25 | <section id="tab-services"> | |
| 26 | <div class="toolbar"> | |
| 27 | <div class="chips" id="filters"> | |
| 28 | <button data-f="all" class="on">All</button> | |
| 29 | <button data-f="active">Active</button> | |
| 30 | <button data-f="problems">Degraded / failed</button> | |
| 31 | <button data-f="dormant">Dormant</button> | |
| 32 | </div> | |
| 33 | <input id="q" type="search" placeholder="Filter by name, port, user…"> | |
| 34 | </div> | |
| 35 | <div id="services" class="list"></div> | |
| 36 | <details class="system"> | |
| 37 | <summary id="system-sum">Operating-system units</summary> | |
| 38 | <div id="system" class="syslist"></div> | |
| 39 | </details> | |
| 40 | </section> | |
| 41 | ||
| 42 | <section id="tab-lan" hidden> | |
| 43 | <div class="toolbar"> | |
| 44 | <span id="lan-meta" class="sub"></span> | |
| 45 | <button id="scan" class="primary">Scan now</button> | |
| 46 | </div> | |
| 47 | <div id="lan" class="list"></div> | |
| 48 | </section> | |
| 49 | ||
| 50 | <script src="/app.js"></script> | |
| 51 | </body> | |
| 52 | </html> |
| … | … | @@ -0,0 +1,127 @@ |
| 1 | // buildServices / stateOf: attribution and states, without a host. | |
| 2 | import test from 'brittle' | |
| 3 | import { buildServices, stateOf, readListeners, pghAppOf } from '../lib/collect.js' | |
| 4 | import fs from 'bare-fs' | |
| 5 | import os from 'bare-os' | |
| 6 | import path from 'bare-path' | |
| 7 | ||
| 8 | const unit = (Id, extra = {}) => ({ | |
| 9 | Id, Description: Id, LoadState: 'loaded', ActiveState: 'active', SubState: 'running', | |
| 10 | UnitFileState: 'enabled', FragmentPath: '/usr/lib/systemd/system/' + Id, User: '', ...extra | |
| 11 | }) | |
| 12 | ||
| 13 | function build (over = {}) { | |
| 14 | return buildServices({ | |
| 15 | listeners: [], | |
| 16 | owners: new Map(), | |
| 17 | pidInfo: new Map(), | |
| 18 | users: new Map([[1000, 'fleeky'], [122, 'jellyfin']]), | |
| 19 | units: [], | |
| 20 | userUnits: [], | |
| 21 | pghApps: [], | |
| 22 | probes: new Map(), | |
| 23 | ...over | |
| 24 | }) | |
| 25 | } | |
| 26 | ||
| 27 | test('a port owned by our own pgh app attaches to that app', (t) => { | |
| 28 | const { services } = build({ | |
| 29 | listeners: [{ port: 4050, addr: '0.0.0.0', scope: 'all', uid: 1000, inodes: [11] }], | |
| 30 | owners: new Map([[11, 500]]), | |
| 31 | pidInfo: new Map([[500, { pid: 500, cmd: 'bare x', pghApp: 'cthuloid-web', unit: null, userUnit: false }]]), | |
| 32 | pghApps: [{ name: 'cthuloid-web', running: true, version: '0.2.1', autostart: true, lastExitCode: 0 }], | |
| 33 | probes: new Map([['4050/0.0.0.0', { open: true, http: { code: 200, title: 'Cthuloid Lights' }, banner: null }]]) | |
| 34 | }) | |
| 35 | t.is(services.length, 1) | |
| 36 | t.is(services[0].id, 'pgh:cthuloid-web') | |
| 37 | t.is(services[0].ports[0].http.title, 'Cthuloid Lights') | |
| 38 | t.is(services[0].state, 'active') | |
| 39 | }) | |
| 40 | ||
| 41 | test('another user\'s socket attaches to the running unit with that User=', (t) => { | |
| 42 | const { services } = build({ | |
| 43 | listeners: [{ port: 8096, addr: '0.0.0.0', scope: 'all', uid: 122, inodes: [9] }], | |
| 44 | units: [unit('jellyfin.service', { User: 'jellyfin' })], | |
| 45 | probes: new Map([['8096/0.0.0.0', { open: true, http: { code: 302 }, banner: null }]]) | |
| 46 | }) | |
| 47 | const j = services.find((s) => s.id === 'unit:jellyfin.service') | |
| 48 | t.ok(j) | |
| 49 | t.is(j.ports[0].port, 8096) | |
| 50 | t.is(j.state, 'active') | |
| 51 | }) | |
| 52 | ||
| 53 | test('a socket nobody can be tied to is its own "port" service', (t) => { | |
| 54 | const { services } = build({ | |
| 55 | listeners: [{ port: 80, addr: '::', scope: 'all', uid: 0, inodes: [1] }], | |
| 56 | probes: new Map([['80/::', { open: true, http: { code: 308 }, banner: null }]]) | |
| 57 | }) | |
| 58 | t.is(services[0].kind, 'port') | |
| 59 | t.is(services[0].ports[0].owner.user, '0') | |
| 60 | }) | |
| 61 | ||
| 62 | test('vendor units without ports go to the system list; hand-made ones stay', (t) => { | |
| 63 | const { services, system } = build({ | |
| 64 | units: [unit('cron.service'), unit('easynews-indexer.service', { FragmentPath: '/etc/systemd/system/easynews-indexer.service' })], | |
| 65 | userUnits: [unit('kodi-repo.service', { FragmentPath: '/home/u/.config/systemd/user/kodi-repo.service' })] | |
| 66 | }) | |
| 67 | t.alike(services.map((s) => s.id).sort(), ['unit:easynews-indexer.service', 'user:kodi-repo.service']) | |
| 68 | t.alike(system.map((s) => s.name), ['cron.service']) | |
| 69 | }) | |
| 70 | ||
| 71 | test('a failed vendor unit is a service, not hidden in the system list', (t) => { | |
| 72 | const { services } = build({ units: [unit('xdg-desktop-portal.service', { ActiveState: 'failed', SubState: 'failed' })] }) | |
| 73 | t.is(services[0].state, 'failed') | |
| 74 | }) | |
| 75 | ||
| 76 | test('pghAppOf: the app is the script, not pgh\'s runtime', (t) => { | |
| 77 | t.is(pghAppOf(['/h/.local/share/store/apps/pgh/runtime/bare', '/h/.local/share/store/apps/favela-web/index.js']), 'favela-web') | |
| 78 | t.is(pghAppOf(['/h/.local/share/store/apps/pgh/runtime/bare', '/h/.local/share/store/apps/pgh/lib/supervisor.js']), 'pgh') | |
| 79 | t.is(pghAppOf(['/usr/bin/python3', '-m', 'http.server']), null) | |
| 80 | }) | |
| 81 | ||
| 82 | test('a plain process\'s ports are one service named after it', (t) => { | |
| 83 | const { services } = build({ | |
| 84 | listeners: [17001, 18080].map((port, i) => ({ port, addr: '::', scope: 'all', uid: 1000, inodes: [i + 1] })), | |
| 85 | owners: new Map([[1, 7684], [2, 7684]]), | |
| 86 | pidInfo: new Map([[7684, { pid: 7684, cmd: 'cogserver', exe: 'cogserver', pghApp: null, unit: null, userUnit: false }]]) | |
| 87 | }) | |
| 88 | t.is(services.length, 1) | |
| 89 | t.is(services[0].kind, 'process') | |
| 90 | t.is(services[0].name, 'cogserver') | |
| 91 | t.is(services[0].ports.length, 2) | |
| 92 | }) | |
| 93 | ||
| 94 | test('a root socket goes to the unit labels.json names for its port', (t) => { | |
| 95 | const { services } = build({ | |
| 96 | listeners: [{ port: 22, addr: '0.0.0.0', scope: 'all', uid: 0, inodes: [1] }], | |
| 97 | units: [unit('ssh.service')], | |
| 98 | labels: { ports: { 22: { name: 'SSH', unit: 'ssh.service' } } } | |
| 99 | }) | |
| 100 | t.is(services.length, 1) | |
| 101 | t.is(services[0].id, 'unit:ssh.service') | |
| 102 | t.is(services[0].ports[0].port, 22) | |
| 103 | }) | |
| 104 | ||
| 105 | test('states', (t) => { | |
| 106 | t.is(stateOf({ kind: 'pgh', running: false, lastExitCode: 0, ports: [] }), 'dormant') | |
| 107 | t.is(stateOf({ kind: 'pgh', running: false, lastExitCode: 75, ports: [] }), 'dormant', '75 = OTA restart') | |
| 108 | t.is(stateOf({ kind: 'pgh', running: false, lastExitCode: 1, ports: [] }), 'failed') | |
| 109 | t.is(stateOf({ kind: 'pgh', running: true, ports: [{ open: false }] }), 'degraded') | |
| 110 | t.is(stateOf({ kind: 'unit', running: false, activeState: 'inactive', ports: [] }), 'dormant') | |
| 111 | t.is(stateOf({ kind: 'unit', running: true, activeState: 'active', ports: [{ open: true }, { open: false }] }), 'active') | |
| 112 | }) | |
| 113 | ||
| 114 | test('readListeners: v4+v6 on the same port and scope are one entry; loopback twin folds into "all"', (t) => { | |
| 115 | const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'hs-')) | |
| 116 | fs.mkdirSync(path.join(dir, 'net')) | |
| 117 | const head = ' sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode\n' | |
| 118 | fs.writeFileSync(path.join(dir, 'net/tcp'), head + | |
| 119 | ' 0: 00000000:1FA0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 122 0 101 1\n' + | |
| 120 | ' 1: 0100007F:1FA0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 122 0 102 1\n') | |
| 121 | fs.writeFileSync(path.join(dir, 'net/tcp6'), head + | |
| 122 | ' 0: 00000000000000000000000000000000:1FA0 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 122 0 103 1\n') | |
| 123 | const ls = readListeners(dir) | |
| 124 | t.is(ls.length, 1, '0.0.0.0, :: and 127.0.0.1 on 8096 are one service') | |
| 125 | t.is(ls[0].scope, 'all') | |
| 126 | t.alike(ls[0].inodes.sort(), [101, 102, 103]) | |
| 127 | }) |
| … | … | @@ -0,0 +1,70 @@ |
| 1 | +;enp2s0;IPv6;I0U4R078n14AAA;_FC9F5ED42C8A._tcp;local | |
| 2 | +;enp2s0;IPv4;I0U4R078n14AAA;_FC9F5ED42C8A._tcp;local | |
| 3 | +;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_privet._tcp;local | |
| 4 | =;enp2s0;IPv6;I0U4R078n14AAA;_FC9F5ED42C8A._tcp;local;Android_RI46Y41R.local;192.168.50.148;53601;"IPv4=192.168.50.148" "n=MsKh27XLSlAUGc4Xs8qzVYU" "f=5180" | |
| 5 | +;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_scanner._tcp;local | |
| 6 | =;enp2s0;IPv4;I0U4R078n14AAA;_FC9F5ED42C8A._tcp;local;Android_RI46Y41R.local;192.168.50.148;53601;"IPv4=192.168.50.148" "n=MsKh27XLSlAUGc4Xs8qzVYU" "f=5180" | |
| 7 | +;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_ipp._tcp;local | |
| 8 | +;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_printer._tcp;local | |
| 9 | +;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_pdl-datastream._tcp;local | |
| 10 | +;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_http._tcp;local | |
| 11 | +;enp2s0;IPv4;BC102F980CE7;_spotify-connect._tcp;local | |
| 12 | =;enp2s0;IPv4;BC102F980CE7;_spotify-connect._tcp;local;BC102F980CE7.local;192.168.50.111;17654;"Stack=SP" "VERSION=1.0" "CPath=/zc/0" | |
| 13 | +;enp2s0;IPv6;SABnzbd\032on\032stortron\0588085;_http._tcp;local | |
| 14 | +;enp2s0;IPv4;SABnzbd\032on\032stortron\0588085;_http._tcp;local | |
| 15 | +;lo;IPv4;SABnzbd\032on\032stortron\0588085;_http._tcp;local | |
| 16 | =;enp2s0;IPv6;SABnzbd\032on\032stortron\0588085;_http._tcp;local;stortron.local;fe80::fb64:bd7f:42fd:ff8c;8085;"https=0" "path=" | |
| 17 | =;enp2s0;IPv4;SABnzbd\032on\032stortron\0588085;_http._tcp;local;stortron.local;192.168.50.215;8085;"https=0" "path=" | |
| 18 | =;lo;IPv4;SABnzbd\032on\032stortron\0588085;_http._tcp;local;stortron.local;127.0.0.1;8085;"https=0" "path=" | |
| 19 | +;enp2s0;IPv4;Kodi\032\040lelectron\041;_http._tcp;local | |
| 20 | =;enp2s0;IPv4;Kodi\032\040lelectron\041;_http._tcp;local;lelectron.local;192.168.50.192;8080;"uuid=401ef5d4-9f34-4606-85cf-c476d3b99393" "txtvers=1" | |
| 21 | +;enp2s0;IPv4;DCA63223F32C\064Kodi\032\040lelectron\041;_raop._tcp;local | |
| 22 | +;enp2s0;IPv4;LELECTRON;_smb._tcp;local | |
| 23 | +;enp2s0;IPv4;lelectron;_sftp-ssh._tcp;local | |
| 24 | +;enp2s0;IPv4;studiolight;_cthuloid._tcp;local | |
| 25 | =;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_pdl-datastream._tcp;local;BRW28565A39CC8D.local;192.168.50.232;9100;"UUID=e3248000-80ce-11db-8000-30055cf6a7c8" "TBCP=T" "Transparent=F" "Binary=T" "PaperCustom=T" "Scan=T" "Fax=T" "Duplex=T" "Copies=T" "Color=F" "usb_CMD=PJL,HBP,URF" "usb_MDL=MFC-L2700DW series" "usb_MFG=Brother" "priority=75" "adminurl=http://BRW28565A39CC8D.local./" "product=(Brother MFC-L2700DW series)" "ty=Brother MFC-L2700DW series" "note=" "pdl=application/octet-stream,image/urf,image/pwg-raster" "qtotal=1" "txtvers=1" | |
| 26 | =;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_printer._tcp;local;BRW28565A39CC8D.local;192.168.50.232;515;"UUID=e3248000-80ce-11db-8000-30055cf6a7c8" "TBCP=F" "Transparent=T" "Binary=T" "PaperCustom=T" "Scan=T" "Fax=T" "Duplex=T" "Copies=T" "Color=F" "usb_CMD=PJL,HBP,URF" "usb_MDL=MFC-L2700DW series" "usb_MFG=Brother" "priority=50" "adminurl=http://BRW28565A39CC8D.local./" "product=(Brother MFC-L2700DW series)" "ty=Brother MFC-L2700DW series" "note=" "rp=duerqxesz5090" "pdl=application/octet-stream,image/urf,image/pwg-raster" "qtotal=1" "txtvers=1" | |
| 27 | =;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_ipp._tcp;local;BRW28565A39CC8D.local;192.168.50.232;631;"print_wfds=T" "UUID=e3248000-80ce-11db-8000-30055cf6a7c8" "PaperMax=legal-A4" "kind=document,envelope,label" "URF=W8,CP1,IS4-1,MT1-3-4-5-8,OB10,PQ4,RS200-300-600,V1.3,DM1" "rfo=ipp/faxout" "TBCP=F" "Transparent=T" "Binary=T" "PaperCustom=T" "Scan=T" "Fax=T" "Duplex=T" "Copies=T" "Color=F" "usb_CMD=PJL,HBP,URF" "usb_MDL=MFC-L2700DW series" "usb_MFG=Brother" "priority=25" "adminurl=http://BRW28565A39CC8D.local./net/net/airprint.html" "product=(Brother MFC-L2700DW series)" "ty=Brother MFC-L2700DW series" "note=" "rp=ipp/print" "pdl=application/octet-stream,image/urf,image/pwg-raster" "qtotal=1" "txtvers=1" | |
| 28 | =;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_scanner._tcp;local;BRW28565A39CC8D.local;192.168.50.232;54921;"flatbed=T" "feeder=T" "button=T" "mdl=MFC-L2700DW series" "mfg=Brother" "ty=Brother MFC-L2700DW series" "adminurl=http://BRW28565A39CC8D.local./" "note=" "txtvers=1" | |
| 29 | =;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_http._tcp;local;BRW28565A39CC8D.local;192.168.50.232;80; | |
| 30 | =;enp2s0;IPv4;Brother\032MFC-L2700DW\032series;_privet._tcp;local;BRW28565A39CC8D.local;192.168.50.232;80;"cs=offline" "id=" "type=printer" "url=https://www.google.com/cloudprint" "note=Brother MFC-L2700DW series [30055cf6a7c8]" "ty=Brother MFC-L2700DW series [28565A39CC8D]" "txtvers=1" | |
| 31 | +;enp2s0;IPv4;SpZc-DB67EF;_spotify-connect._tcp;local | |
| 32 | =;enp2s0;IPv4;SpZc-DB67EF;_spotify-connect._tcp;local;PS5-DB67EF.local;192.168.50.211;41800;"CPath=/spConn" | |
| 33 | +;enp2s0;IPv6;Jason\226\128\153s\032MacBook\032Pro;_airplay._tcp;local | |
| 34 | +;enp2s0;IPv4;Jason\226\128\153s\032MacBook\032Pro;_airplay._tcp;local | |
| 35 | +;enp2s0;IPv6;Jason\226\128\153s\032MacBook\032Pro;_companion-link._tcp;local | |
| 36 | +;enp2s0;IPv4;Jason\226\128\153s\032MacBook\032Pro;_companion-link._tcp;local | |
| 37 | +;enp2s0;IPv4;studiolight;_telnet._tcp;local | |
| 38 | +;enp2s0;IPv4;studiolight;_arduino._tcp;local | |
| 39 | =;enp2s0;IPv4;studiolight;_cthuloid._tcp;local;studiolight.local;192.168.50.89;1337;"proto=3" | |
| 40 | =;enp2s0;IPv4;studiolight;_telnet._tcp;local;studiolight.local;192.168.50.89;23; | |
| 41 | =;enp2s0;IPv4;studiolight;_arduino._tcp;local;studiolight.local;192.168.50.89;3232;"board=esp32" "tcp_check=no" "ssh_upload=no" "auth_upload=yes" | |
| 42 | +;enp2s0;IPv4;Kodi\032\040lelectron\041;_xbmc-jsonrpc-h._tcp;local | |
| 43 | +;enp2s0;IPv4;lelectron;_ssh._tcp;local | |
| 44 | +;enp2s0;IPv4;root\064lelectron;_pulse-server._tcp;local | |
| 45 | +;enp2s0;IPv4;root\064lelectron\058\032Dummy\032Output;_pulse-sink._tcp;local | |
| 46 | +;enp2s0;IPv4;LELECTRON;_device-info._tcp;local | |
| 47 | +;enp2s0;IPv4;Kodi\032\040lelectron\041;_xbmc-events._udp;local | |
| 48 | +;enp2s0;IPv4;Kodi\032\040lelectron\041;_xbmc-jsonrpc._tcp;local | |
| 49 | =;enp2s0;IPv4;lelectron;_sftp-ssh._tcp;local;lelectron.local;192.168.50.192;22;"u=root" "path=/storage" | |
| 50 | =;enp2s0;IPv4;LELECTRON;_smb._tcp;local;lelectron.local;192.168.50.192;445; | |
| 51 | =;enp2s0;IPv4;DCA63223F32C\064Kodi\032\040lelectron\041;_raop._tcp;local;lelectron.local;192.168.50.192;36666;"vs=130.14" "am=Kodi,1" "md=0,1,2" "da=true" "vn=3" "pw=false" "sr=44100" "ss=16" "sm=false" "tp=UDP" "sv=false" "et=0,1" "ek=1" "ch=2" "cn=0,1" "txtvers=1" | |
| 52 | =;enp2s0;IPv4;Kodi\032\040lelectron\041;_xbmc-jsonrpc-h._tcp;local;lelectron.local;192.168.50.192;8080;"uuid=401ef5d4-9f34-4606-85cf-c476d3b99393" "txtvers=1" | |
| 53 | =;enp2s0;IPv4;lelectron;_ssh._tcp;local;lelectron.local;192.168.50.192;22; | |
| 54 | =;enp2s0;IPv4;root\064lelectron;_pulse-server._tcp;local;lelectron.local;192.168.50.192;4713;"cookie=0x738cb2a9" "fqdn=lelectron" "uname=Linux aarch64 6.12.56 #1 SMP Sat Nov 1 08:49:19 UTC 2025" "machine-id=8d987161ce07b8c5b70220cd685d085d" "user-name=root" "server-version=pulseaudio 17.0" | |
| 55 | =;enp2s0;IPv4;root\064lelectron\058\032Dummy\032Output;_pulse-sink._tcp;local;lelectron.local;192.168.50.192;4713;"icon-name=computer" "class=abstract" "description=Dummy Output" "subtype=virtual" "channel_map=front-left,front-right" "format=s16le" "channels=2" "rate=44100" "device=auto_null" "cookie=0x738cb2a9" "fqdn=lelectron" "uname=Linux aarch64 6.12.56 #1 SMP Sat Nov 1 08:49:19 UTC 2025" "machine-id=8d987161ce07b8c5b70220cd685d085d" "user-name=root" "server-version=pulseaudio 17.0" | |
| 56 | =;enp2s0;IPv4;LELECTRON;_device-info._tcp;local;lelectron.local;192.168.50.192;0;"model=Xserve" | |
| 57 | =;enp2s0;IPv4;Kodi\032\040lelectron\041;_xbmc-events._udp;local;lelectron.local;192.168.50.192;9777; | |
| 58 | =;enp2s0;IPv4;Kodi\032\040lelectron\041;_xbmc-jsonrpc._tcp;local;lelectron.local;192.168.50.192;9090;"uuid=401ef5d4-9f34-4606-85cf-c476d3b99393" "txtvers=1" | |
| 59 | +;enp2s0;IPv4;6A164B0C4947\064Jason\226\128\153s\032MacBook\032Pro;_raop._tcp;local | |
| 60 | =;enp2s0;IPv4;Jason\226\128\153s\032MacBook\032Pro;_airplay._tcp;local;Jasons-MacBook-Pro.local;192.168.50.52;7000;"srcvers=960.13.1" "pk=521aea2e165bb6383bbb0240515b1778c96e62325c9d21beade3b0d44f21cc2c" "psi=68164B0C-4947-4659-9E58-78F7523E30F9" "pi=81520dc4-6388-4832-a587-9ed8dc2f6a3b" "protovers=1.1" "at=4" "model=MacBookPro16,2" "gcgl=0" "igl=0" "gid=85145821-17D5-436D-A50E-32F01136CDB6" "flags=0x204" "rsf=0x8" "features=0x4A7FCFD5,0x38174FDE" "fex=1c9/St5PFzg2IQxA" "deviceid=6A:16:4B:0C:49:47" "acl=0" "act=2" | |
| 61 | =;enp2s0;IPv4;Jason\226\128\153s\032MacBook\032Pro;_companion-link._tcp;local;Jasons-MacBook-Pro.local;192.168.50.52;61624;"rpVr=715.2" "rpMac=0" "rpHN=cac65d3cb6e1" "rpFl=0x20000" "rpAD=3fef83b4fe7d" "rpBA=95:96:4C:06:36:06" | |
| 62 | +;enp2s0;IPv6;6A164B0C4947\064Jason\226\128\153s\032MacBook\032Pro;_raop._tcp;local | |
| 63 | =;enp2s0;IPv6;Jason\226\128\153s\032MacBook\032Pro;_airplay._tcp;local;Jasons-MacBook-Pro.local;192.168.50.52;7000;"srcvers=960.13.1" "pk=521aea2e165bb6383bbb0240515b1778c96e62325c9d21beade3b0d44f21cc2c" "psi=68164B0C-4947-4659-9E58-78F7523E30F9" "pi=81520dc4-6388-4832-a587-9ed8dc2f6a3b" "protovers=1.1" "at=4" "model=MacBookPro16,2" "gcgl=0" "igl=0" "gid=85145821-17D5-436D-A50E-32F01136CDB6" "flags=0x204" "rsf=0x8" "features=0x4A7FCFD5,0x38174FDE" "fex=1c9/St5PFzg2IQxA" "deviceid=6A:16:4B:0C:49:47" "acl=0" "act=2" | |
| 64 | =;enp2s0;IPv6;Jason\226\128\153s\032MacBook\032Pro;_companion-link._tcp;local;Jasons-MacBook-Pro.local;192.168.50.52;61624;"rpVr=715.2" "rpMac=0" "rpHN=cac65d3cb6e1" "rpFl=0x20000" "rpAD=3fef83b4fe7d" "rpBA=95:96:4C:06:36:06" | |
| 65 | =;enp2s0;IPv4;6A164B0C4947\064Jason\226\128\153s\032MacBook\032Pro;_raop._tcp;local;Jasons-MacBook-Pro.local;192.168.50.52;7000;"vv=0" "vs=960.13.1" "vn=65537" "tp=UDP" "pk=521aea2e165bb6383bbb0240515b1778c96e62325c9d21beade3b0d44f21cc2c" "am=MacBookPro16,2" "md=0,1,2" "sf=0x204" "ft=0x4A7FCFD5,0x38174FDE" "et=0,3,5" "da=true" "cn=0,1,2,3" | |
| 66 | =;enp2s0;IPv6;6A164B0C4947\064Jason\226\128\153s\032MacBook\032Pro;_raop._tcp;local;Jasons-MacBook-Pro.local;192.168.50.52;7000;"vv=0" "vs=960.13.1" "vn=65537" "tp=UDP" "pk=521aea2e165bb6383bbb0240515b1778c96e62325c9d21beade3b0d44f21cc2c" "am=MacBookPro16,2" "md=0,1,2" "sf=0x204" "ft=0x4A7FCFD5,0x38174FDE" "et=0,3,5" "da=true" "cn=0,1,2,3" | |
| 67 | +;enp2s0;IPv4;seedlings;_http._tcp;local | |
| 68 | =;enp2s0;IPv4;seedlings;_http._tcp;local;seedlings.local;192.168.50.176;80; | |
| 69 | +;enp2s0;IPv4;seedlings;_wled._tcp;local | |
| 70 | =;enp2s0;IPv4;seedlings;_wled._tcp;local;seedlings.local;192.168.50.176;80;"mac=483fda540665" |
| … | … | @@ -0,0 +1,2 @@ |
| 1 | 2: enp2s0 inet 192.168.50.215/24 brd 192.168.50.255 scope global dynamic noprefixroute enp2s0\ valid_lft 44734sec preferred_lft 44734sec | |
| 2 | 4: tunnel0 inet 10.22.0.2/16 scope global tunnel0\ valid_lft forever preferred_lft forever |
| … | … | @@ -0,0 +1,20 @@ |
| 1 | name running supervisorPid childPid version startedAt lastExit lastExitCode autostart log installedAt processStartedAt uptimeSeconds skewSeconds stale staleReason | |
| 2 | ------------------- ------- ------------- -------- -------- ------------------------ ------------------------ ------------ --------- ---------------------------------------------- ------------------------ ------------------------ ------------- ----------- ----- ----------- | |
| 3 | hyper-proto-peer false 0.3.135 2026-10-14T15:01:59.311Z 2026-10-14T15:14:44.731Z 0 false /run/user/1000/pgh/hyper-proto-peer/app.log 2026-10-14T18:35:45.068Z false not running | |
| 4 | atproto-bridge false 0.9.56 2026-10-13T02:52:32.703Z 2026-10-13T22:12:48.816Z 0 false /run/user/1000/pgh/atproto-bridge/app.log 2026-10-14T14:54:07.792Z false not running | |
| 5 | cthuloid-web true 1945131 1945148 0.2.1 2026-10-02T15:26:57.008Z 2026-10-02T15:26:52.544Z 0 true /run/user/1000/pgh/cthuloid-web/app.log 2026-10-02T15:26:56.028Z 2026-10-11T21:53:26.201Z 701207 -800790 false | |
| 6 | hyper-tps false 0.1618.0 false /run/user/1000/pgh/hyper-tps/app.log 2026-10-20T00:24:15.424Z false not running | |
| 7 | favela-web false 0.3.92 2026-10-20T00:21:47.988Z 2026-10-20T00:23:40.438Z 0 false /run/user/1000/pgh/favela-web/app.log 2026-09-30T00:13:41.860Z false not running | |
| 8 | favela-gateway true 2366963 2508944 0.6.6 2026-10-14T00:45:23.524Z 2026-10-15T00:56:46.461Z 75 true /run/user/1000/pgh/favela-gateway/app.log 2026-10-15T00:56:31.180Z 2026-10-15T00:56:47.050Z 431006 -16 false | |
| 9 | favela-peer false 0.0.67 2026-10-13T01:36:07.494Z 2026-10-14T15:14:42.629Z 0 false /run/user/1000/pgh/favela-peer/app.log 2026-10-15T00:56:24.249Z false not running | |
| 10 | atproto-pds false 0.1.0 false /run/user/1000/pgh/atproto-pds/app.log 2026-10-13T23:27:23.072Z false not running | |
| 11 | mirall-cli false 0.1.5 false /run/user/1000/pgh/mirall-cli/app.log 2026-07-25T00:27:36.372Z false not running | |
| 12 | pgh-hello false 0.1.2 false /run/user/1000/pgh/pgh-hello/app.log 2026-05-12T15:58:45.312Z false not running | |
| 13 | atproto-blind-relay false 0.9.10 false /run/user/1000/pgh/atproto-blind-relay/app.log 2026-07-13T17:03:26.812Z false not running | |
| 14 | pgh-sidecar true 2358645 2358660 0.2.69 2026-10-13T23:24:35.123Z 2026-10-13T23:24:34.854Z 0 true /run/user/1000/pgh/pgh-sidecar/app.log 2026-10-13T23:20:07.412Z 2026-10-13T23:24:36.961Z 522936 -270 false | |
| 15 | pear-git-v3 true 2244397 2244407 0.1.254 2026-10-13T02:53:32.945Z 2026-10-13T02:53:31.804Z 1 true /run/user/1000/pgh/pear-git-v3/app.log 2026-10-11T22:33:35.845Z 2026-10-13T02:53:32.959Z 596800 -101997 false | |
| 16 | git-remote-punch false 0.1.8 false /run/user/1000/pgh/git-remote-punch/app.log 2026-07-29T01:38:54.946Z false not running | |
| 17 | favela-host true 2448356 2508970 0.1.17 2026-10-14T15:14:45.618Z 2026-10-15T00:56:51.301Z 75 true /run/user/1000/pgh/favela-host/app.log 2026-10-15T00:56:45.943Z 2026-10-19T01:31:39.225Z 83314 -347693 false | |
| 18 | favela-surface false 0.0.69 2026-10-13T02:53:15.831Z 2026-10-14T15:14:40.057Z false /run/user/1000/pgh/favela-surface/app.log 2026-10-15T00:54:15.002Z false not running | |
| 19 | ap-bridge false 0.10.22 2026-10-13T02:52:02.295Z 2026-10-13T22:12:52.158Z 0 false /run/user/1000/pgh/ap-bridge/app.log 2026-10-15T00:56:08.090Z false not running | |
| 20 | pgh false 0.1.162 false /run/user/1000/pgh/pgh/app.log 2026-10-14T00:44:56.470Z false not running |
| … | … | @@ -0,0 +1,18 @@ |
| 1 | IP address HW type Flags HW address Mask Device | |
| 2 | 192.168.50.228 0x1 0x2 98:22:ef:58:0f:97 * enp2s0 | |
| 3 | 192.168.50.232 0x1 0x2 28:56:5a:39:cc:8d * enp2s0 | |
| 4 | 192.168.50.114 0x1 0x2 10:7b:44:25:f9:37 * enp2s0 | |
| 5 | 192.168.50.218 0x1 0x2 bc:a5:11:f9:1a:5f * enp2s0 | |
| 6 | 192.168.50.153 0x1 0x2 9e:35:af:2b:e2:16 * enp2s0 | |
| 7 | 192.168.50.161 0x1 0x0 00:00:00:00:00:00 * enp2s0 | |
| 8 | 192.168.50.211 0x1 0x2 1c:98:c1:38:8c:76 * enp2s0 | |
| 9 | 192.168.50.165 0x1 0x2 3a:af:f9:36:83:d0 * enp2s0 | |
| 10 | 192.168.50.16 0x1 0x2 3a:ab:ee:a0:53:3c * enp2s0 | |
| 11 | 192.168.50.192 0x1 0x2 dc:a6:32:23:f3:2c * enp2s0 | |
| 12 | 192.168.50.1 0x1 0x2 d4:13:f8:38:88:80 * enp2s0 | |
| 13 | 192.168.50.89 0x1 0x2 3c:71:bf:84:d9:c8 * enp2s0 | |
| 14 | 192.168.50.162 0x1 0x0 00:00:00:00:00:00 * enp2s0 | |
| 15 | 192.168.50.185 0x1 0x2 e8:38:a0:31:cc:e6 * enp2s0 | |
| 16 | 192.168.50.216 0x1 0x2 b4:2e:99:31:b6:d3 * enp2s0 | |
| 17 | 192.168.50.52 0x1 0x2 c6:1d:03:b3:66:52 * enp2s0 | |
| 18 | 192.168.50.224 0x1 0x2 f2:14:00:88:4e:f6 * enp2s0 |
| … | … | @@ -0,0 +1,236 @@ |
| 1 | sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode | |
| 2 | 0: 00000000:0D47 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 920516479 1 0000000000000000 100 0 0 10 0 | |
| 3 | 1: 00000000:0D48 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 920519412 1 0000000000000000 100 0 0 10 0 | |
| 4 | 2: 00000000:0D49 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 920516493 1 0000000000000000 100 0 0 10 0 | |
| 5 | 3: 0100007F:0FCA 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 920516487 1 0000000000000000 100 0 0 10 0 | |
| 6 | 4: 00000000:0FD2 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 705544823 1 0000000000000000 100 0 0 10 0 | |
| 7 | 5: 0100007F:07E3 00000000:0000 0A 00000000:00000000 00:00000000 00000000 995 0 14414 1 0000000000000000 100 0 0 10 0 | |
| 8 | 6: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 926668073 1 0000000000000000 100 0 0 10 0 | |
| 9 | 7: 0100007F:82A5 00000000:0000 0A 00000000:00000000 00:00000000 00000000 997 0 12119 1 0000000000000000 100 0 0 10 0 | |
| 10 | 8: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 9910 1 0000000000000000 100 0 0 10 0 | |
| 11 | 9: 00000000:1C34 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 926521468 1 0000000000000000 100 0 0 10 0 | |
| 12 | 10: 00000000:1C35 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 13945 1 0000000000000000 100 0 0 10 0 | |
| 13 | 11: 00000000:1FA0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 122 0 19578 1 0000000000000000 100 0 0 10 0 | |
| 14 | 12: 00000000:1F95 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 17459 1 0000000000000000 100 0 0 10 0 | |
| 15 | 13: 00000000:1F91 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 10939 1 0000000000000000 100 0 0 10 0 | |
| 16 | 14: 00000000:138D 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 917890145 1 0000000000000000 100 0 0 10 0 | |
| 17 | 15: 0100007F:7E91 00000000:0000 0A 00000000:00000000 00:00000000 00000000 997 0 13643 1 0000000000000000 100 0 0 10 0 | |
| 18 | 16: 0100007F:7F58 00000000:0000 0A 00000000:00000000 00:00000000 00000000 997 0 14628 1 0000000000000000 100 0 0 10 0 | |
| 19 | 17: 3600007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 991 0 7946 1 0000000000000000 100 0 0 10 5 | |
| 20 | 18: 3500007F:0035 00000000:0000 0A 00000000:00001001 00:00000000 00000000 991 0 7944 4098 0000000000000000 100 0 0 10 5 | |
| 21 | 19: 0200160A:138D 0300160A:D3DE 01 00000000:00000000 00:00000000 00000000 1000 0 923211138 1 0000000000000000 31 4 31 10 -1 | |
| 22 | 20: 0200160A:0D47 0300160A:9C1E 01 00000000:00000000 00:00000000 00000000 1000 0 922972370 1 0000000000000000 30 4 31 2 2 | |
| 23 | 21: D732A8C0:1FA0 C032A8C0:B118 01 00000000:00000000 00:00000000 00000000 122 0 926451775 1 0000000000000000 20 4 31 10 -1 | |
| 24 | 22: 0200160A:138D 0300160A:9796 01 00000000:00000000 00:00000000 00000000 1000 0 925273326 1 0000000000000000 30 4 31 10 109 | |
| 25 | 23: 0200160A:138D 0300160A:AD4A 01 00000000:00000000 00:00000000 00000000 1000 0 922899846 1 0000000000000000 30 4 31 10 -1 | |
| 26 | 24: 0200160A:138D 0300160A:D008 01 00000000:00000000 00:00000000 00000000 1000 0 928060227 1 0000000000000000 30 4 30 12 30 | |
| 27 | 25: 0200160A:138D 0300160A:9922 01 00000000:00000000 00:00000000 00000000 1000 0 926631616 1 0000000000000000 30 4 31 10 30 | |
| 28 | 26: 0200160A:138D 0300160A:BCA6 01 00000000:00000000 00:00000000 00000000 1000 0 926661520 1 0000000000000000 35 4 31 16 31 | |
| 29 | 27: 0200160A:138D 0300160A:9D68 01 00000000:00000000 00:00000000 00000000 1000 0 927724839 1 0000000000000000 38 4 31 10 -1 | |
| 30 | 28: 0200160A:138D 0300160A:BC90 01 00000000:00000000 00:00000000 00000000 1000 0 926965704 1 0000000000000000 30 4 31 10 51 | |
| 31 | 29: D732A8C0:D166 7DD868AC:01BB 01 00000000:000C1396 00:00000000 00000000 997 0 918165505 1 0000000000000000 23 4 30 10 -1 | |
| 32 | 30: 2632A8C0:A4AA 2129D22C:01BB 08 00000000:00000001 00:00000000 00000000 997 0 12619 1 0000000000000000 25 4 20 10 -1 | |
| 33 | 31: 0200160A:138D 0300160A:BC82 01 00000000:00000000 00:00000000 00000000 1000 0 926965703 1 0000000000000000 30 4 31 10 30 | |
| 34 | 32: 0200160A:0D47 0300160A:9174 06 00000000:00000000 03:00000FFD 00000000 0 0 0 3 0000000000000000 | |
| 35 | 33: 0200160A:138D 0300160A:B890 01 00000000:00000000 00:00000000 00000000 1000 0 927999493 1 0000000000000000 69 4 31 10 28 | |
| 36 | 34: 0200160A:138D 0300160A:D574 01 00000000:00000000 00:00000000 00000000 1000 0 923182209 1 0000000000000000 42 4 31 10 207 | |
| 37 | 35: 0200160A:138D 0300160A:D9CA 01 00000000:00000000 00:00000000 00000000 1000 0 927442955 1 0000000000000000 30 4 31 10 40 | |
| 38 | 36: 0100007F:EB28 0100007F:1FA0 06 00000000:00000000 03:00001713 00000000 0 0 0 3 0000000000000000 | |
| 39 | 37: 0200160A:138D 0300160A:A552 01 00000000:00000000 00:00000000 00000000 1000 0 922952758 1 0000000000000000 30 4 30 14 -1 | |
| 40 | 38: 0200160A:138D 0300160A:AD4C 01 00000000:00000000 00:00000000 00000000 1000 0 925346889 1 0000000000000000 30 4 31 10 31 | |
| 41 | 39: D732A8C0:941A 47858A9B:01BB 01 00000000:00000000 02:0001C1A0 00000000 1000 0 927370987 2 0000000000000000 25 4 31 10 -1 | |
| 42 | 40: 0200160A:138D 0300160A:A3B0 01 00000000:00000000 00:00000000 00000000 1000 0 920749151 1 0000000000000000 46 4 31 10 -1 | |
| 43 | 41: 0200160A:138D 0300160A:DCCC 01 00000000:00000000 00:00000000 00000000 1000 0 922998471 1 0000000000000000 30 4 30 14 54 | |
| 44 | 42: 0200160A:138D 0300160A:BC74 01 00000000:00000000 00:00000000 00000000 1000 0 926965702 1 0000000000000000 31 4 31 16 -1 | |
| 45 | 43: 0200160A:138D 0300160A:D152 01 00000000:00000000 00:00000000 00000000 1000 0 926061103 1 0000000000000000 31 4 30 21 -1 | |
| 46 | 44: 2632A8C0:A4B8 2129D22C:01BB 08 00000000:00000001 00:00000000 00000000 997 0 12629 1 0000000000000000 25 4 28 10 -1 | |
| 47 | 45: 0200160A:0D47 0300160A:E122 01 00000000:00000000 00:00000000 00000000 1000 0 927306458 1 0000000000000000 29 4 31 10 -1 | |
| 48 | 46: 0200160A:138D 0300160A:C9EC 01 00000000:00000000 00:00000000 00000000 1000 0 927695418 1 0000000000000000 50 4 30 12 30 | |
| 49 | 47: 0200160A:138D 0300160A:8456 01 00000000:00000000 00:00000000 00000000 1000 0 927247221 1 0000000000000000 30 4 33 10 49 | |
| 50 | 48: 0200160A:138D 0300160A:99F4 01 00000000:00000000 00:00000000 00000000 1000 0 926572287 1 0000000000000000 30 4 31 10 13 | |
| 51 | 49: 0200160A:0D47 0300160A:D792 01 00000000:00000000 00:00000000 00000000 1000 0 926590753 1 0000000000000000 29 4 31 7 7 | |
| 52 | 50: 0100007F:EB48 0100007F:1FA0 06 00000000:00000000 03:0000156C 00000000 0 0 0 3 0000000000000000 | |
| 53 | 51: 0200160A:138D 0300160A:BA5C 01 00000000:00000000 00:00000000 00000000 1000 0 923294888 1 0000000000000000 29 4 31 10 -1 | |
| 54 | 52: 0200160A:138D 0300160A:BA54 01 00000000:00000000 00:00000000 00000000 1000 0 923294886 1 0000000000000000 29 4 31 10 -1 | |
| 55 | 53: 0100007F:EB3A 0100007F:1FA0 06 00000000:00000000 03:00001713 00000000 0 0 0 3 0000000000000000 | |
| 56 | 54: 0100007F:EB32 0100007F:1FA0 06 00000000:00000000 03:00001714 00000000 0 0 0 3 0000000000000000 | |
| 57 | 55: 0200160A:138D 0300160A:9CF6 01 00000000:00000000 00:00000000 00000000 1000 0 925046713 1 0000000000000000 30 4 30 14 -1 | |
| 58 | 56: 0200160A:138D 0300160A:BA28 01 00000000:00000000 00:00000000 00000000 1000 0 926571733 1 0000000000000000 30 4 30 7 6 | |
| 59 | 57: 0200160A:138D 0300160A:B278 01 00000000:00000000 00:00000000 00000000 1000 0 922878906 1 0000000000000000 30 4 31 10 -1 | |
| 60 | 58: 0200160A:0D47 0300160A:A440 01 00000000:00000000 00:00000000 00000000 1000 0 922961276 1 0000000000000000 29 4 31 2 2 | |
| 61 | 59: 0200160A:138D 0300160A:D8AA 01 00000000:00000000 00:00000000 00000000 1000 0 926731436 1 0000000000000000 30 4 33 10 56 | |
| 62 | 60: 0200160A:0D47 0300160A:DC6A 06 00000000:00000000 03:0000130D 00000000 0 0 0 3 0000000000000000 | |
| 63 | 61: 0200160A:138D 0300160A:C9DC 01 00000000:00000000 00:00000000 00000000 1000 0 927695416 1 0000000000000000 33 4 31 10 -1 | |
| 64 | 62: 0200160A:138D 0300160A:D4C2 01 00000000:00000000 00:00000000 00000000 1000 0 927675113 1 0000000000000000 30 4 31 10 58 | |
| 65 | 63: 0200160A:138D 0300160A:9C4E 01 00000000:00000000 00:00000000 00000000 1000 0 927604078 1 0000000000000000 31 4 33 10 -1 | |
| 66 | 64: 0200160A:0D47 0300160A:A70A 01 00000000:00000000 00:00000000 00000000 1000 0 923200164 1 0000000000000000 29 4 31 2 2 | |
| 67 | 65: 2632A8C0:A876 CD9740AC:01BB 08 00000000:00000001 00:00000000 00000000 997 0 13887 1 0000000000000000 23 4 24 10 -1 | |
| 68 | 66: 0200160A:138D 0300160A:DBE4 01 00000000:00000000 00:00000000 00000000 1000 0 926731382 1 0000000000000000 30 4 31 10 121 | |
| 69 | 67: 0200160A:138D 0300160A:E6C4 01 00000000:00000000 00:00000000 00000000 1000 0 923288670 1 0000000000000000 30 4 31 10 -1 | |
| 70 | 68: 0200160A:138D 0300160A:9892 01 00000000:00000000 00:00000000 00000000 1000 0 926575108 1 0000000000000000 29 4 31 10 -1 | |
| 71 | 69: 0100007F:1F95 0100007F:CF8E 06 00000000:00000000 03:00000D4D 00000000 0 0 0 3 0000000000000000 | |
| 72 | 70: 0200160A:138D 0300160A:A10E 01 00000000:00000000 00:00000000 00000000 1000 0 927893733 1 0000000000000000 39 4 32 12 30 | |
| 73 | 71: 0100007F:EB0A 0100007F:1FA0 06 00000000:00000000 03:0000156C 00000000 0 0 0 3 0000000000000000 | |
| 74 | 72: 0200160A:138D 0300160A:8012 01 00000000:00000000 00:00000000 00000000 1000 0 926552620 1 0000000000000000 31 4 31 7 7 | |
| 75 | 73: 0200160A:0D47 0300160A:D75A 01 00000000:00000000 00:00000000 00000000 1000 0 926591241 1 0000000000000000 30 4 31 7 7 | |
| 76 | 74: 0200160A:138D 0300160A:CA8E 01 00000000:00000000 00:00000000 00000000 1000 0 926575809 1 0000000000000000 30 4 31 10 62 | |
| 77 | 75: 0200160A:138D 0300160A:A5A4 01 00000000:00000000 00:00000000 00000000 1000 0 920946762 1 0000000000000000 30 4 30 14 -1 | |
| 78 | 76: 2632A8C0:A866 CD9740AC:01BB 08 00000000:00000001 00:00000000 00000000 997 0 13886 1 0000000000000000 23 4 20 10 -1 | |
| 79 | 77: 0200160A:138D 0300160A:C7CE 01 00000000:00000000 00:00000000 00000000 1000 0 926592181 1 0000000000000000 30 4 33 10 -1 | |
| 80 | 78: 0200160A:0D47 0300160A:8D54 01 00000000:00000000 00:00000000 00000000 1000 0 927661090 1 0000000000000000 30 4 31 10 -1 | |
| 81 | 79: 0200160A:0D47 0300160A:A91C 06 00000000:00000000 03:0000027E 00000000 0 0 0 3 0000000000000000 | |
| 82 | 80: 0200160A:138D 0300160A:BC6E 01 00000000:00000000 00:00000000 00000000 1000 0 926965696 1 0000000000000000 30 4 31 10 31 | |
| 83 | 81: 0200160A:138D 0300160A:8366 01 00000000:00000000 00:00000000 00000000 1000 0 927441517 1 0000000000000000 39 4 31 16 30 | |
| 84 | 82: 0100007F:EB1A 0100007F:1FA0 06 00000000:00000000 03:00001714 00000000 0 0 0 3 0000000000000000 | |
| 85 | 83: 0200160A:0D47 0300160A:D8E0 06 00000000:00000000 03:00001530 00000000 0 0 0 3 0000000000000000 | |
| 86 | 84: 0200160A:138D 0300160A:B322 01 00000000:00000000 00:00000000 00000000 1000 0 922908199 1 0000000000000000 30 4 31 10 -1 | |
| 87 | 85: 0200160A:138D 0300160A:AA8A 01 00000000:00000000 00:00000000 00000000 1000 0 926849102 1 0000000000000000 30 4 30 10 -1 | |
| 88 | 86: 0200160A:138D 0300160A:DBDE 01 00000000:00000000 00:00000000 00000000 1000 0 926731381 1 0000000000000000 32 4 30 10 48 | |
| 89 | 87: 0200160A:0D47 0300160A:D76A 01 00000000:00000000 00:00000000 00000000 1000 0 926591245 1 0000000000000000 29 4 31 10 -1 | |
| 90 | 88: 0200160A:138D 0300160A:9A2A 01 00000000:00000000 00:00000000 00000000 1000 0 923317852 1 0000000000000000 30 4 30 14 -1 | |
| 91 | 89: 0200160A:0D47 0300160A:A436 01 00000000:00000000 00:00000000 00000000 1000 0 922961275 1 0000000000000000 30 4 31 2 2 | |
| 92 | 90: 0200160A:138D 0300160A:D3FA 01 00000000:00000000 00:00000000 00000000 1000 0 923211141 1 0000000000000000 47 4 29 16 -1 | |
| 93 | 91: 0200160A:138D 0300160A:DBC0 01 00000000:00000000 00:00000000 00000000 1000 0 926731377 1 0000000000000000 30 4 30 10 -1 | |
| 94 | 92: 0200160A:0D47 0300160A:D786 01 00000000:00000000 00:00000000 00000000 1000 0 926592074 1 0000000000000000 30 4 31 10 -1 | |
| 95 | 93: 0200160A:138D 0300160A:80D6 01 00000000:00000000 00:00000000 00000000 1000 0 927611412 1 0000000000000000 31 4 31 10 56 | |
| 96 | 94: 0200160A:0D47 0300160A:8D56 01 00000000:00000000 00:00000000 00000000 1000 0 927661091 1 0000000000000000 30 4 31 10 -1 | |
| 97 | 95: 0200160A:138D 0300160A:C080 01 00000000:00000000 00:00000000 00000000 1000 0 920553878 1 0000000000000000 32 4 31 10 56 | |
| 98 | 96: 0200160A:138D 0300160A:8368 01 00000000:00000000 00:00000000 00000000 1000 0 927441518 1 0000000000000000 30 4 30 14 30 | |
| 99 | 97: 0100007F:EB62 0100007F:1FA0 06 00000000:00000000 03:00001713 00000000 0 0 0 3 0000000000000000 | |
| 100 | 98: 0200160A:138D 0300160A:8D7C 01 00000000:00000000 00:00000000 00000000 1000 0 927999470 1 0000000000000000 30 4 30 21 -1 | |
| 101 | 99: 0200160A:0D47 0300160A:BE48 01 00000000:00000000 00:00000000 00000000 1000 0 927816490 1 0000000000000000 29 4 31 10 -1 | |
| 102 | 100: 0200160A:0D47 0300160A:A74A 01 00000000:00000000 00:00000000 00000000 1000 0 926557590 1 0000000000000000 29 4 31 10 -1 | |
| 103 | 101: 0200160A:138D 0300160A:B906 01 00000000:00000000 00:00000000 00000000 1000 0 926621500 1 0000000000000000 30 4 31 10 63 | |
| 104 | 102: 0200160A:138D 0300160A:9D80 01 00000000:00000000 00:00000000 00000000 1000 0 927724841 1 0000000000000000 37 4 31 10 -1 | |
| 105 | 103: 0100007F:82A5 0100007F:8A32 01 00000000:00000000 00:00000000 00000000 997 0 12121 1 0000000000000000 20 4 30 10 -1 | |
| 106 | 104: D732A8C0:CEF8 5932A8C0:0539 01 00000000:00000000 00:00000000 00000000 1000 0 927818754 1 0000000000000000 20 4 28 10 -1 | |
| 107 | 105: 0200160A:138D 0300160A:E082 01 00000000:00000000 00:00000000 00000000 1000 0 923227703 1 0000000000000000 32 4 31 16 -1 | |
| 108 | 106: 0200160A:138D 0300160A:B866 01 00000000:00000000 00:00000000 00000000 1000 0 922978286 1 0000000000000000 35 4 31 12 28 | |
| 109 | 107: 0200160A:138D 0300160A:B31E 01 00000000:00000000 00:00000000 00000000 1000 0 922908198 1 0000000000000000 30 4 31 10 -1 | |
| 110 | 108: 0200160A:138D 0300160A:AD5A 01 00000000:00000000 00:00000000 00000000 1000 0 925346923 1 0000000000000000 31 4 30 10 37 | |
| 111 | 109: 0200160A:0D47 0300160A:A42C 01 00000000:00000000 00:00000000 00000000 1000 0 922968183 1 0000000000000000 29 4 31 2 2 | |
| 112 | 110: 0200160A:138D 0300160A:8B7A 01 00000000:00000000 00:00000000 00000000 1000 0 927610420 1 0000000000000000 32 4 31 10 30 | |
| 113 | 111: 0200160A:0D47 0300160A:CB72 01 00000000:00000000 00:00000000 00000000 1000 0 926720577 1 0000000000000000 29 4 31 10 -1 | |
| 114 | 112: 0200160A:138D 0300160A:D3FC 01 00000000:00000000 00:00000000 00000000 1000 0 923211142 1 0000000000000000 33 4 32 12 -1 | |
| 115 | 113: D732A8C0:0016 D832A8C0:CC9C 01 00000000:00000000 02:000AFC65 00000000 0 0 928086354 3 0000000000000000 20 4 13 14 -1 | |
| 116 | 114: 0200160A:138D 0300160A:DBE8 01 00000000:00000000 00:00000000 00000000 1000 0 926731383 1 0000000000000000 30 4 30 16 58 | |
| 117 | 115: 0200160A:138D 0300160A:DBCE 01 00000000:00000000 00:00000000 00000000 1000 0 926731378 1 0000000000000000 30 4 30 10 -1 | |
| 118 | 116: 0200160A:138D 0300160A:9D84 01 00000000:00000000 00:00000000 00000000 1000 0 927724843 1 0000000000000000 30 4 31 10 30 | |
| 119 | 117: 0100007F:1F91 0100007F:E900 06 00000000:00000000 03:0000017F 00000000 0 0 0 3 0000000000000000 | |
| 120 | 118: 0200160A:138D 0300160A:BC64 01 00000000:00000000 00:00000000 00000000 1000 0 926965695 1 0000000000000000 30 4 31 10 -1 | |
| 121 | 119: 0200160A:138D 0300160A:B472 01 00000000:00000000 00:00000000 00000000 1000 0 926795332 1 0000000000000000 30 4 30 10 -1 | |
| 122 | 120: 0200160A:0D47 0300160A:A41E 01 00000000:00000000 00:00000000 00000000 1000 0 922961272 1 0000000000000000 30 4 31 2 2 | |
| 123 | 121: 0200160A:138D 0300160A:DC36 01 00000000:00000000 00:00000000 00000000 1000 0 926040175 1 0000000000000000 38 4 31 10 30 | |
| 124 | 122: 0200160A:138D 0300160A:DB12 01 00000000:00000000 00:00000000 00000000 1000 0 920460096 1 0000000000000000 34 4 31 16 -1 | |
| 125 | 123: 0200160A:138D 0300160A:B32C 01 00000000:00000000 00:00000000 00000000 1000 0 922908200 1 0000000000000000 30 4 31 10 -1 | |
| 126 | 124: 0200160A:0D47 0300160A:8D52 01 00000000:00000000 00:00000000 00000000 1000 0 927319211 1 0000000000000000 30 4 31 2 7 | |
| 127 | 125: 0200160A:138D 0300160A:A81C 01 00000000:00000000 00:00000000 00000000 1000 0 922971964 1 0000000000000000 170 4 30 25 -1 | |
| 128 | 126: 0200160A:138D 0300160A:D0D0 01 00000000:00000000 00:00000000 00000000 1000 0 925051361 1 0000000000000000 30 4 31 16 -1 | |
| 129 | 127: 0200160A:138D 0300160A:9CDE 01 00000000:00000000 00:00000000 00000000 1000 0 925046711 1 0000000000000000 30 4 31 10 -1 | |
| 130 | 128: 0200160A:138D 0300160A:8158 01 00000000:00000000 00:00000000 00000000 1000 0 925981377 1 0000000000000000 30 4 31 10 -1 | |
| 131 | 129: 0200160A:138D 0300160A:9884 01 00000000:00000000 00:00000000 00000000 1000 0 926575107 1 0000000000000000 29 4 31 10 -1 | |
| 132 | 130: 0100007F:1F95 0100007F:CF80 06 00000000:00000000 03:00000D4D 00000000 0 0 0 3 0000000000000000 | |
| 133 | 131: D732A8C0:9E6C 65DA68AC:01BB 01 00000000:00000000 00:00000000 00000000 997 0 927740601 1 0000000000000000 22 4 30 10 -1 | |
| 134 | 132: 0200160A:138D 0300160A:9CD2 01 00000000:00000000 00:00000000 00000000 1000 0 925046710 1 0000000000000000 30 4 31 10 -1 | |
| 135 | 133: 0200160A:0D47 0300160A:BD30 01 00000000:00000000 00:00000000 00000000 1000 0 926517011 1 0000000000000000 30 4 31 2 2 | |
| 136 | 134: 0200160A:138D 0300160A:8EFA 01 00000000:00000000 00:00000000 00000000 1000 0 927011454 1 0000000000000000 30 4 31 10 -1 | |
| 137 | 135: 0200160A:138D 0300160A:D204 01 00000000:00000000 00:00000000 00000000 1000 0 926976562 1 0000000000000000 30 4 30 14 33 | |
| 138 | 136: 0200160A:0D47 0300160A:D7A2 01 00000000:00000000 00:00000000 00000000 1000 0 926591269 1 0000000000000000 29 4 31 10 -1 | |
| 139 | 137: 0200160A:138D 0300160A:C992 01 00000000:00000000 00:00000000 00000000 1000 0 926593220 1 0000000000000000 32 4 30 10 56 | |
| 140 | 138: 0200160A:0D47 0300160A:9416 06 00000000:00000000 03:00001656 00000000 0 0 0 3 0000000000000000 | |
| 141 | 139: 0200160A:0D47 0300160A:9902 01 00000000:00000000 00:00000000 00000000 1000 0 927816520 1 0000000000000000 29 4 31 10 -1 | |
| 142 | 140: 0200160A:0D47 0300160A:EC32 01 00000000:00000000 00:00000000 00000000 1000 0 928086353 1 0000000000000000 29 4 31 10 -1 | |
| 143 | 141: D732A8C0:8890 4EAB9C36:01BB 08 00000000:00000019 00:00000000 00000000 997 0 928078099 1 0000000000000000 23 4 28 10 -1 | |
| 144 | 142: 0200160A:138D 0300160A:9698 01 00000000:00000000 00:00000000 00000000 1000 0 928011042 1 0000000000000000 52 4 31 10 -1 | |
| 145 | 143: 0200160A:0D47 0300160A:E4D0 01 00000000:00000000 00:00000000 00000000 1000 0 920558397 1 0000000000000000 32 4 30 2 2 | |
| 146 | 144: 0200160A:138D 0300160A:8CA8 01 00000000:00000000 00:00000000 00000000 1000 0 926458598 1 0000000000000000 31 4 32 8 4 | |
| 147 | 145: 0200160A:0D47 0300160A:D794 01 00000000:00000000 00:00000000 00000000 1000 0 926591266 1 0000000000000000 30 4 31 10 -1 | |
| 148 | 146: 0200160A:138D 0300160A:B9E6 01 00000000:00000000 00:00000000 00000000 1000 0 927095249 1 0000000000000000 31 4 31 10 -1 | |
| 149 | 147: 0200160A:138D 0300160A:CF7A 01 00000000:00000000 00:00000000 00000000 1000 0 927422025 1 0000000000000000 29 4 31 10 30 | |
| 150 | 148: 0200160A:0D47 0300160A:91AC 01 00000000:00000000 00:00000000 00000000 1000 0 928009958 1 0000000000000000 29 4 31 10 -1 | |
| 151 | 149: 0200160A:0D47 0300160A:E648 01 00000000:00000000 00:00000000 00000000 1000 0 924997857 1 0000000000000000 31 4 31 2 2 | |
| 152 | 150: 0200160A:138D 0300160A:9D8A 01 00000000:00000000 00:00000000 00000000 1000 0 927724842 1 0000000000000000 32 4 31 10 -1 | |
| 153 | 151: 0200160A:138D 0300160A:B63A 01 00000000:00000000 00:00000000 00000000 1000 0 926403278 1 0000000000000000 30 4 30 7 7 | |
| 154 | 152: 0200160A:138D 0300160A:8160 01 00000000:00000000 00:00000000 00000000 1000 0 925981378 1 0000000000000000 30 4 31 10 -1 | |
| 155 | 153: 0200160A:138D 0300160A:A898 01 00000000:00000000 00:00000000 00000000 1000 0 924935463 1 0000000000000000 30 4 31 10 -1 | |
| 156 | 154: 0200160A:0D47 0300160A:D774 01 00000000:00000000 00:00000000 00000000 1000 0 926592068 1 0000000000000000 30 4 31 10 -1 | |
| 157 | 155: 0200160A:0D47 0300160A:EC2C 01 00000000:00000000 00:00000000 00000000 1000 0 928086349 1 0000000000000000 29 4 31 10 -1 | |
| 158 | 156: 0200160A:138D 0300160A:B3CE 01 00000000:00000000 00:00000000 00000000 1000 0 926713060 1 0000000000000000 30 4 31 10 89 | |
| 159 | 157: 0200160A:138D 0300160A:A3AC 01 00000000:00000000 00:00000000 00000000 1000 0 920749150 1 0000000000000000 30 4 31 10 -1 | |
| 160 | 158: 0200160A:138D 0300160A:D82E 01 00000000:00000000 00:00000000 00000000 1000 0 927345394 1 0000000000000000 30 4 32 12 -1 | |
| 161 | 159: 0200160A:138D 0300160A:99A8 01 00000000:00000000 00:00000000 00000000 1000 0 923316882 1 0000000000000000 30 4 30 12 -1 | |
| 162 | 160: 0100007F:EB42 0100007F:1FA0 06 00000000:00000000 03:00001714 00000000 0 0 0 3 0000000000000000 | |
| 163 | 161: 0200160A:138D 0300160A:845E 01 00000000:00000000 00:00000000 00000000 1000 0 927260274 1 0000000000000000 30 4 31 10 -1 | |
| 164 | 162: 0200160A:138D 0300160A:9CFC 01 00000000:00000000 00:00000000 00000000 1000 0 925046714 1 0000000000000000 30 4 30 12 -1 | |
| 165 | 163: 0200160A:138D 0300160A:E142 01 00000000:00000000 00:00000000 00000000 1000 0 927665976 1 0000000000000000 33 4 31 10 -1 | |
| 166 | 164: 0200160A:138D 0300160A:C41E 01 00000000:00000000 00:00000000 00000000 1000 0 927429511 1 0000000000000000 33 4 28 10 -1 | |
| 167 | 165: 0200160A:138D 0300160A:A5AA 01 00000000:00000000 00:00000000 00000000 1000 0 920946764 1 0000000000000000 30 4 31 10 -1 | |
| 168 | 166: 0200160A:0D47 0300160A:A44C 01 00000000:00000000 00:00000000 00000000 1000 0 922966952 1 0000000000000000 30 4 31 2 2 | |
| 169 | 167: 0200160A:138D 0300160A:DB7C 01 00000000:00000000 00:00000000 00000000 1000 0 923281134 1 0000000000000000 60 4 30 80 92 | |
| 170 | 168: 0200160A:138D 0300160A:E352 01 00000000:00000000 00:00000000 00000000 1000 0 927369730 1 0000000000000000 30 4 30 14 -1 | |
| 171 | 169: 0200160A:138D 0300160A:A860 01 00000000:00000000 00:00000000 00000000 1000 0 928079450 1 0000000000000000 30 4 30 12 -1 | |
| 172 | 170: 0200160A:138D 0300160A:BA64 01 00000000:00000000 00:00000000 00000000 1000 0 923294890 1 0000000000000000 30 4 30 12 -1 | |
| 173 | 171: 0200160A:138D 0300160A:A3A4 01 00000000:00000000 00:00000000 00000000 1000 0 920749149 1 0000000000000000 30 4 31 10 94 | |
| 174 | 172: 0200160A:138D 0300160A:8A12 01 00000000:00000000 00:00000000 00000000 1000 0 926845443 1 0000000000000000 30 4 31 10 -1 | |
| 175 | 173: 0200160A:138D 0300160A:BA4A 01 00000000:00000000 00:00000000 00000000 1000 0 923294885 1 0000000000000000 29 4 31 10 -1 | |
| 176 | 174: 0200160A:138D 0300160A:9582 01 00000000:00000000 00:00000000 00000000 1000 0 927413156 1 0000000000000000 29 4 31 10 -1 | |
| 177 | 175: 0200160A:0D47 0300160A:E438 01 00000000:00000000 00:00000000 00000000 1000 0 925984811 1 0000000000000000 29 4 31 3 2 | |
| 178 | 176: 0200160A:138D 0300160A:99EA 01 00000000:00000000 00:00000000 00000000 1000 0 926575532 1 0000000000000000 35 4 30 10 -1 | |
| 179 | 177: 0200160A:138D 0300160A:D7BE 01 00000000:00000000 00:00000000 00000000 1000 0 925898839 1 0000000000000000 31 4 32 10 -1 | |
| 180 | 178: 0200160A:138D 0300160A:8CC2 01 00000000:00000000 00:00000000 00000000 1000 0 923220864 1 0000000000000000 38 4 31 10 -1 | |
| 181 | 179: 0200160A:138D 0300160A:9CEC 01 00000000:00000000 00:00000000 00000000 1000 0 925046712 1 0000000000000000 30 4 31 10 -1 | |
| 182 | 180: 0100007F:EB5A 0100007F:1FA0 06 00000000:00000000 03:00001712 00000000 0 0 0 3 0000000000000000 | |
| 183 | 181: 0200160A:138D 0300160A:C1A6 01 00000000:00000000 00:00000000 00000000 1000 0 920474893 1 0000000000000000 30 4 31 10 168 | |
| 184 | 182: 0100007F:EB60 0100007F:1FA0 06 00000000:00000000 03:00001712 00000000 0 0 0 3 0000000000000000 | |
| 185 | 183: 0200160A:138D 0300160A:87E8 01 00000000:00000000 00:00000000 00000000 1000 0 927847826 1 0000000000000000 30 4 32 72 332 | |
| 186 | 184: 0200160A:138D 0300160A:B942 01 00000000:00000000 00:00000000 00000000 1000 0 926567880 1 0000000000000000 30 4 31 10 54 | |
| 187 | 185: 0200160A:138D 0300160A:BEE4 01 00000000:00000000 00:00000000 00000000 1000 0 928075938 1 0000000000000000 31 4 30 12 -1 | |
| 188 | 186: 0200160A:138D 0300160A:A5A8 01 00000000:00000000 00:00000000 00000000 1000 0 920946763 1 0000000000000000 30 4 31 10 -1 | |
| 189 | 187: 0200160A:0D47 0300160A:B980 01 00000000:00000000 00:00000000 00000000 1000 0 926523365 1 0000000000000000 29 4 31 2 4 | |
| 190 | 188: 0200160A:138D 0300160A:B62A 01 00000000:00000000 00:00000000 00000000 1000 0 926403276 1 0000000000000000 30 4 30 10 7 | |
| 191 | 189: 0200160A:138D 0300160A:9CC4 01 00000000:00000000 00:00000000 00000000 1000 0 925046709 1 0000000000000000 39 4 31 10 -1 | |
| 192 | 190: 0200160A:138D 0300160A:C2D2 01 00000000:00000000 00:00000000 00000000 1000 0 923113230 1 0000000000000000 30 4 31 10 -1 | |
| 193 | 191: 0200160A:138D 0300160A:D656 01 00000000:00000000 00:00000000 00000000 1000 0 926574213 1 0000000000000000 30 4 33 10 22 | |
| 194 | 192: 0100007F:E2FC 0100007F:25E0 01 00000000:00000000 00:00000000 00000000 1000 0 928077766 1 0000000000000000 20 4 30 10 -1 | |
| 195 | 193: 0200160A:138D 0300160A:ACB6 01 00000000:00000000 00:00000000 00000000 1000 0 926354438 1 0000000000000000 30 4 33 10 28 | |
| 196 | 194: 0200160A:138D 0300160A:941C 01 00000000:00000000 00:00000000 00000000 1000 0 925061600 1 0000000000000000 29 4 31 10 -1 | |
| 197 | 195: 0200160A:0D47 0300160A:D76C 01 00000000:00000000 00:00000000 00000000 1000 0 926592067 1 0000000000000000 29 4 31 10 -1 | |
| 198 | 196: 0200160A:0D47 0300160A:D1D0 01 00000000:00000000 00:00000000 00000000 1000 0 927996134 1 0000000000000000 29 4 31 10 -1 | |
| 199 | 197: 0200160A:0D47 0300160A:B51E 06 00000000:00000000 03:0000067B 00000000 0 0 0 3 0000000000000000 | |
| 200 | 198: 0200160A:138D 0300160A:BA56 01 00000000:00000000 00:00000000 00000000 1000 0 923294887 1 0000000000000000 30 4 31 10 -1 | |
| 201 | 199: 0200160A:0D47 0300160A:DC7A 05 00000000:00000000 03:00001264 00000000 0 0 0 3 0000000000000000 | |
| 202 | 200: D732A8C0:1FA0 C032A8C0:C81C 01 00000000:00000000 00:00000000 00000000 122 0 926450704 1 0000000000000000 20 4 31 7 7 | |
| 203 | 201: 0200160A:138D 0300160A:87A8 01 00000000:00000000 00:00000000 00000000 1000 0 923211765 1 0000000000000000 34 4 30 10 -1 | |
| 204 | 202: 0200160A:138D 0300160A:C75C 01 00000000:00000000 00:00000000 00000000 1000 0 923263574 1 0000000000000000 93 4 31 10 88 | |
| 205 | 203: 0200160A:138D 0300160A:D270 01 00000000:00000000 00:00000000 00000000 1000 0 927755395 1 0000000000000000 42 4 31 10 30 | |
| 206 | 204: 0200160A:0D47 0300160A:D764 01 00000000:00000000 00:00000000 00000000 1000 0 926591240 1 0000000000000000 29 4 31 7 7 | |
| 207 | 205: 0200160A:138D 0300160A:A050 01 00000000:00000000 00:00000000 00000000 1000 0 927679668 1 0000000000000000 30 4 31 10 -1 | |
| 208 | 206: 0200160A:0D47 0300160A:D778 01 00000000:00000000 00:00000000 00000000 1000 0 926592072 1 0000000000000000 33 4 31 10 -1 | |
| 209 | 207: 0200160A:138D 0300160A:BCA0 01 00000000:00000000 00:00000000 00000000 1000 0 926965705 1 0000000000000000 30 4 31 10 40 | |
| 210 | 208: 0200160A:138D 0300160A:DCE6 01 00000000:00000000 00:00000000 00000000 1000 0 928006648 1 0000000000000000 33 4 30 14 -1 | |
| 211 | 209: 0200160A:138D 0300160A:D1FE 01 00000000:00000000 00:00000000 00000000 1000 0 926976561 1 0000000000000000 30 4 31 10 30 | |
| 212 | 210: 0200160A:138D 0300160A:C6CE 01 00000000:00000000 00:00000000 00000000 1000 0 926605114 1 0000000000000000 30 4 31 10 -1 | |
| 213 | 211: 0200160A:138D 0300160A:C860 01 00000000:00000000 00:00000000 00000000 1000 0 923193725 1 0000000000000000 66 4 29 23 -1 | |
| 214 | 212: 0100007F:EB52 0100007F:1FA0 06 00000000:00000000 03:00001712 00000000 0 0 0 3 0000000000000000 | |
| 215 | 213: 0200160A:138D 0300160A:B75A 01 00000000:00000000 00:00000000 00000000 1000 0 927975718 1 0000000000000000 39 4 33 10 28 | |
| 216 | 214: 0200160A:138D 0300160A:B33A 01 00000000:00000000 00:00000000 00000000 1000 0 922908202 1 0000000000000000 32 4 31 10 -1 | |
| 217 | 215: 0200160A:138D 0300160A:A596 01 00000000:00000000 00:00000000 00000000 1000 0 920946760 1 0000000000000000 29 4 31 10 -1 | |
| 218 | 216: 0200160A:138D 0300160A:AC36 01 00000000:00000000 00:00000000 00000000 1000 0 928011730 1 0000000000000000 63 4 31 10 28 | |
| 219 | 217: 0200160A:138D 0300160A:A59C 01 00000000:00000000 00:00000000 00000000 1000 0 920946761 1 0000000000000000 29 4 31 10 -1 | |
| 220 | 218: 0100007F:8A32 0100007F:82A5 01 00000000:00000000 00:00000000 00000000 997 0 12618 1 0000000000000000 20 4 4 10 -1 | |
| 221 | 219: 0200160A:138D 0300160A:D834 01 00000000:00000000 00:00000000 00000000 1000 0 927345395 1 0000000000000000 29 4 31 10 -1 | |
| 222 | 220: 0200160A:138D 0300160A:8E6C 01 00000000:00000000 00:00000000 00000000 1000 0 923282287 1 0000000000000000 30 4 29 10 28 | |
| 223 | 221: 0200160A:138D 0300160A:D3EE 01 00000000:00000000 00:00000000 00000000 1000 0 923211139 1 0000000000000000 30 4 31 10 -1 | |
| 224 | 222: 0200160A:138D 0300160A:8098 01 00000000:00000000 00:00000000 00000000 1000 0 926857696 1 0000000000000000 30 4 33 16 -1 | |
| 225 | 223: 0200160A:138D 0300160A:DAD8 01 00000000:00000000 00:00000000 00000000 1000 0 926359570 1 0000000000000000 30 4 30 8 7 | |
| 226 | 224: 0200160A:0D47 0300160A:D7A6 01 00000000:00000000 00:00000000 00000000 1000 0 926591270 1 0000000000000000 30 4 31 10 -1 | |
| 227 | 225: 0200160A:138D 0300160A:B644 01 00000000:00000000 00:00000000 00000000 1000 0 926403279 1 0000000000000000 34 4 31 10 -1 | |
| 228 | 226: 0200160A:138D 0300160A:B626 01 00000000:00000000 00:00000000 00000000 1000 0 926403275 1 0000000000000000 37 4 30 10 -1 | |
| 229 | 227: 0200160A:138D 0300160A:C9F4 01 00000000:00000000 00:00000000 00000000 1000 0 927695419 1 0000000000000000 30 4 31 10 -1 | |
| 230 | 228: 0200160A:138D 0300160A:96A6 01 00000000:00000000 00:00000000 00000000 1000 0 928011043 1 0000000000000000 46 4 31 10 -1 | |
| 231 | 229: 0200160A:138D 0300160A:D74A 01 00000000:00000000 00:00000000 00000000 1000 0 926864638 1 0000000000000000 30 4 31 10 -1 | |
| 232 | 230: 0200160A:0D47 0300160A:B2D4 01 00000000:00000000 00:00000000 00000000 1000 0 926592066 1 0000000000000000 30 4 31 10 -1 | |
| 233 | 231: 0200160A:0D47 0300160A:B978 01 00000000:00000000 00:00000000 00000000 1000 0 926534806 1 0000000000000000 29 4 31 2 2 | |
| 234 | 232: 0200160A:0D47 0300160A:B2E0 01 00000000:00000000 00:00000000 00000000 1000 0 926592071 1 0000000000000000 34 4 31 10 -1 | |
| 235 | 233: 0200160A:0D47 0300160A:A430 01 00000000:00000000 00:00000000 00000000 1000 0 922961274 1 0000000000000000 29 4 31 2 2 | |
| 236 | 234: 0100007F:EB6E 0100007F:1FA0 06 00000000:00000000 03:00001712 00000000 0 0 0 3 0000000000000000 |
| … | … | @@ -0,0 +1,12 @@ |
| 1 | sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode | |
| 2 | 0: 00000000000000000000000001000000:0277 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 926668072 1 0000000000000000 100 0 0 10 0 | |
| 3 | 1: 00000000000000000000000000000000:01BB 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 995 0 12061 1 0000000000000000 100 0 0 10 0 | |
| 4 | 2: 00000000000000000000000000000000:0016 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 7123 1 0000000000000000 100 0 0 10 0 | |
| 5 | 3: 00000000000000000000000000000000:0050 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 995 0 12060 1 0000000000000000 100 0 0 10 0 | |
| 6 | 4: 00000000000000000000000000000000:1EC6 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 4037 1 0000000000000000 100 0 0 10 0 | |
| 7 | 5: 00000000000000000000000000000000:13BF 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 14803 1 0000000000000000 100 0 0 10 0 | |
| 8 | 6: 00000000000000000000000000000000:25E0 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 14658 1 0000000000000000 100 0 0 10 0 | |
| 9 | 7: 00000000000000000000000000000000:231D 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12781 1 0000000000000000 100 0 0 10 0 | |
| 10 | 8: 00000000000000000000000000000000:7E90 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 997 0 13641 1 0000000000000000 100 0 0 10 0 | |
| 11 | 9: 0000000000000000FFFF00000100007F:25E0 0000000000000000FFFF00000100007F:E2FC 01 00000000:00000000 00:00000000 00000000 1000 0 928078795 1 0000000000000000 20 4 30 10 -1 | |
| 12 | 10: 000080FE000000007FBD64FB8CFFFD42:0016 000080FE00000000A8D77C0417F0D5AC:F341 01 00000000:00000000 02:0007C3D5 00000000 0 0 927507861 2 0000000000000000 22 4 30 17 13 |
| … | … | @@ -0,0 +1,2078 @@ |
| 1 | MainPID=0 | |
| 2 | User= | |
| 3 | Id=accounts-daemon.service | |
| 4 | Description=Accounts Service | |
| 5 | LoadState=loaded | |
| 6 | ActiveState=inactive | |
| 7 | SubState=dead | |
| 8 | FragmentPath=/usr/lib/systemd/system/accounts-daemon.service | |
| 9 | UnitFileState=enabled | |
| 10 | ActiveEnterTimestamp= | |
| 11 | ||
| 12 | MainPID=0 | |
| 13 | User= | |
| 14 | Id=alsa-restore.service | |
| 15 | Description=Save/Restore Sound Card State | |
| 16 | LoadState=loaded | |
| 17 | ActiveState=active | |
| 18 | SubState=exited | |
| 19 | FragmentPath=/usr/lib/systemd/system/alsa-restore.service | |
| 20 | UnitFileState=static | |
| 21 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:08 EDT | |
| 22 | ||
| 23 | MainPID=0 | |
| 24 | User= | |
| 25 | Id=alsa-state.service | |
| 26 | Description=Manage Sound Card State (restore and store) | |
| 27 | LoadState=loaded | |
| 28 | ActiveState=inactive | |
| 29 | SubState=dead | |
| 30 | FragmentPath=/usr/lib/systemd/system/alsa-state.service | |
| 31 | UnitFileState=static | |
| 32 | ActiveEnterTimestamp= | |
| 33 | ||
| 34 | MainPID=0 | |
| 35 | User= | |
| 36 | Id=anacron.service | |
| 37 | Description=Run anacron jobs | |
| 38 | LoadState=loaded | |
| 39 | ActiveState=inactive | |
| 40 | SubState=dead | |
| 41 | FragmentPath=/usr/lib/systemd/system/anacron.service | |
| 42 | UnitFileState=enabled | |
| 43 | ActiveEnterTimestamp=Mon 2026-10-19 20:34:26 EDT | |
| 44 | ||
| 45 | MainPID=0 | |
| 46 | User= | |
| 47 | Id=apparmor.service | |
| 48 | Description=Load AppArmor profiles | |
| 49 | LoadState=loaded | |
| 50 | ActiveState=active | |
| 51 | SubState=exited | |
| 52 | FragmentPath=/usr/lib/systemd/system/apparmor.service | |
| 53 | UnitFileState=enabled | |
| 54 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:02 EDT | |
| 55 | ||
| 56 | MainPID=0 | |
| 57 | User= | |
| 58 | Id=apt-daily-upgrade.service | |
| 59 | Description=Daily apt upgrade and clean activities | |
| 60 | LoadState=loaded | |
| 61 | ActiveState=inactive | |
| 62 | SubState=dead | |
| 63 | FragmentPath=/usr/lib/systemd/system/apt-daily-upgrade.service | |
| 64 | UnitFileState=static | |
| 65 | ActiveEnterTimestamp= | |
| 66 | ||
| 67 | MainPID=0 | |
| 68 | User= | |
| 69 | Id=apt-daily.service | |
| 70 | Description=Daily apt download activities | |
| 71 | LoadState=loaded | |
| 72 | ActiveState=inactive | |
| 73 | SubState=dead | |
| 74 | FragmentPath=/usr/lib/systemd/system/apt-daily.service | |
| 75 | UnitFileState=static | |
| 76 | ActiveEnterTimestamp= | |
| 77 | ||
| 78 | MainPID=0 | |
| 79 | User= | |
| 80 | Id=auditd.service | |
| 81 | Description=auditd.service | |
| 82 | LoadState=not-found | |
| 83 | ActiveState=inactive | |
| 84 | SubState=dead | |
| 85 | FragmentPath= | |
| 86 | UnitFileState= | |
| 87 | ActiveEnterTimestamp= | |
| 88 | ||
| 89 | MainPID=0 | |
| 90 | User= | |
| 91 | Id=auto-cpufreq.service | |
| 92 | Description=auto-cpufreq.service | |
| 93 | LoadState=not-found | |
| 94 | ActiveState=inactive | |
| 95 | SubState=dead | |
| 96 | FragmentPath= | |
| 97 | UnitFileState= | |
| 98 | ActiveEnterTimestamp= | |
| 99 | ||
| 100 | MainPID=772 | |
| 101 | User= | |
| 102 | Id=avahi-daemon.service | |
| 103 | Description=Avahi mDNS/DNS-SD Stack | |
| 104 | LoadState=loaded | |
| 105 | ActiveState=active | |
| 106 | SubState=running | |
| 107 | FragmentPath=/usr/lib/systemd/system/avahi-daemon.service | |
| 108 | UnitFileState=enabled | |
| 109 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:12 EDT | |
| 110 | ||
| 111 | MainPID=0 | |
| 112 | User= | |
| 113 | Id=avahi.service | |
| 114 | Description=avahi.service | |
| 115 | LoadState=not-found | |
| 116 | ActiveState=inactive | |
| 117 | SubState=dead | |
| 118 | FragmentPath= | |
| 119 | UnitFileState= | |
| 120 | ActiveEnterTimestamp= | |
| 121 | ||
| 122 | MainPID=0 | |
| 123 | User= | |
| 124 | Id=blk-availability.service | |
| 125 | Description=Availability of block devices | |
| 126 | LoadState=loaded | |
| 127 | ActiveState=active | |
| 128 | SubState=exited | |
| 129 | FragmentPath=/usr/lib/systemd/system/blk-availability.service | |
| 130 | UnitFileState=enabled | |
| 131 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:46 EDT | |
| 132 | ||
| 133 | MainPID=0 | |
| 134 | User= | |
| 135 | Id=blueman-mechanism.service | |
| 136 | Description=Bluetooth management mechanism | |
| 137 | LoadState=loaded | |
| 138 | ActiveState=inactive | |
| 139 | SubState=dead | |
| 140 | FragmentPath=/usr/lib/systemd/system/blueman-mechanism.service | |
| 141 | UnitFileState=enabled | |
| 142 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:36 EDT | |
| 143 | ||
| 144 | MainPID=774 | |
| 145 | User= | |
| 146 | Id=bluetooth.service | |
| 147 | Description=Bluetooth service | |
| 148 | LoadState=loaded | |
| 149 | ActiveState=active | |
| 150 | SubState=running | |
| 151 | FragmentPath=/usr/lib/systemd/system/bluetooth.service | |
| 152 | UnitFileState=enabled | |
| 153 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:12 EDT | |
| 154 | ||
| 155 | MainPID=1059 | |
| 156 | User=caddy | |
| 157 | Id=caddy.service | |
| 158 | Description=Caddy | |
| 159 | LoadState=loaded | |
| 160 | ActiveState=active | |
| 161 | SubState=running | |
| 162 | FragmentPath=/usr/lib/systemd/system/caddy.service | |
| 163 | UnitFileState=enabled | |
| 164 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:56 EDT | |
| 165 | ||
| 166 | MainPID=0 | |
| 167 | User= | |
| 168 | Id=casper-md5check.service | |
| 169 | Description=casper-md5check.service | |
| 170 | LoadState=masked | |
| 171 | ActiveState=inactive | |
| 172 | SubState=dead | |
| 173 | FragmentPath=/etc/systemd/system/casper-md5check.service | |
| 174 | UnitFileState=masked | |
| 175 | ActiveEnterTimestamp= | |
| 176 | ||
| 177 | MainPID=0 | |
| 178 | User= | |
| 179 | Id=casper.service | |
| 180 | Description=Shuts down the "live" preinstalled system cleanly | |
| 181 | LoadState=loaded | |
| 182 | ActiveState=inactive | |
| 183 | SubState=dead | |
| 184 | FragmentPath=/usr/lib/systemd/system/casper.service | |
| 185 | UnitFileState=enabled | |
| 186 | ActiveEnterTimestamp= | |
| 187 | ||
| 188 | MainPID=1113 | |
| 189 | User=colord | |
| 190 | Id=colord.service | |
| 191 | Description=Manage, Install and Generate Color Profiles | |
| 192 | LoadState=loaded | |
| 193 | ActiveState=active | |
| 194 | SubState=running | |
| 195 | FragmentPath=/usr/lib/systemd/system/colord.service | |
| 196 | UnitFileState=static | |
| 197 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:42 EDT | |
| 198 | ||
| 199 | MainPID=0 | |
| 200 | User= | |
| 201 | Id=connman.service | |
| 202 | Description=connman.service | |
| 203 | LoadState=not-found | |
| 204 | ActiveState=inactive | |
| 205 | SubState=dead | |
| 206 | FragmentPath= | |
| 207 | UnitFileState= | |
| 208 | ActiveEnterTimestamp= | |
| 209 | ||
| 210 | MainPID=0 | |
| 211 | User= | |
| 212 | Id=console-screen.service | |
| 213 | Description=console-screen.service | |
| 214 | LoadState=not-found | |
| 215 | ActiveState=inactive | |
| 216 | SubState=dead | |
| 217 | FragmentPath= | |
| 218 | UnitFileState= | |
| 219 | ActiveEnterTimestamp= | |
| 220 | ||
| 221 | MainPID=0 | |
| 222 | User= | |
| 223 | Id=console-setup.service | |
| 224 | Description=Set console font and keymap | |
| 225 | LoadState=loaded | |
| 226 | ActiveState=active | |
| 227 | SubState=exited | |
| 228 | FragmentPath=/usr/lib/systemd/system/console-setup.service | |
| 229 | UnitFileState=enabled | |
| 230 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:00 EDT | |
| 231 | ||
| 232 | MainPID=775 | |
| 233 | User= | |
| 234 | Id=cron.service | |
| 235 | Description=Regular background program processing daemon | |
| 236 | LoadState=loaded | |
| 237 | ActiveState=active | |
| 238 | SubState=running | |
| 239 | FragmentPath=/usr/lib/systemd/system/cron.service | |
| 240 | UnitFileState=enabled | |
| 241 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:07 EDT | |
| 242 | ||
| 243 | MainPID=3095285 | |
| 244 | User=cups-browsed | |
| 245 | Id=cups-browsed.service | |
| 246 | Description=Make remote CUPS printers available locally | |
| 247 | LoadState=loaded | |
| 248 | ActiveState=active | |
| 249 | SubState=running | |
| 250 | FragmentPath=/usr/lib/systemd/system/cups-browsed.service | |
| 251 | UnitFileState=enabled | |
| 252 | ActiveEnterTimestamp=Mon 2026-10-19 00:00:13 EDT | |
| 253 | ||
| 254 | MainPID=3095283 | |
| 255 | User= | |
| 256 | Id=cups.service | |
| 257 | Description=CUPS Scheduler | |
| 258 | LoadState=loaded | |
| 259 | ActiveState=active | |
| 260 | SubState=running | |
| 261 | FragmentPath=/usr/lib/systemd/system/cups.service | |
| 262 | UnitFileState=enabled | |
| 263 | ActiveEnterTimestamp=Mon 2026-10-19 00:00:13 EDT | |
| 264 | ||
| 265 | MainPID=776 | |
| 266 | User= | |
| 267 | Id=dbus.service | |
| 268 | Description=D-Bus System Message Bus | |
| 269 | LoadState=loaded | |
| 270 | ActiveState=active | |
| 271 | SubState=running | |
| 272 | FragmentPath=/usr/lib/systemd/system/dbus.service | |
| 273 | UnitFileState=static | |
| 274 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:12 EDT | |
| 275 | ||
| 276 | MainPID=0 | |
| 277 | User= | |
| 278 | Id=dm-event.service | |
| 279 | Description=Device-mapper event daemon | |
| 280 | LoadState=loaded | |
| 281 | ActiveState=inactive | |
| 282 | SubState=dead | |
| 283 | FragmentPath=/usr/lib/systemd/system/dm-event.service | |
| 284 | UnitFileState=static | |
| 285 | ActiveEnterTimestamp= | |
| 286 | ||
| 287 | MainPID=0 | |
| 288 | User= | |
| 289 | Id=dmesg.service | |
| 290 | Description=Save initial kernel messages after boot | |
| 291 | LoadState=loaded | |
| 292 | ActiveState=inactive | |
| 293 | SubState=dead | |
| 294 | FragmentPath=/usr/lib/systemd/system/dmesg.service | |
| 295 | UnitFileState=enabled | |
| 296 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:07 EDT | |
| 297 | ||
| 298 | MainPID=0 | |
| 299 | User= | |
| 300 | Id=dpkg-db-backup.service | |
| 301 | Description=Daily dpkg database backup service | |
| 302 | LoadState=loaded | |
| 303 | ActiveState=inactive | |
| 304 | SubState=dead | |
| 305 | FragmentPath=/usr/lib/systemd/system/dpkg-db-backup.service | |
| 306 | UnitFileState=static | |
| 307 | ActiveEnterTimestamp= | |
| 308 | ||
| 309 | MainPID=0 | |
| 310 | User= | |
| 311 | Id=e2scrub_all.service | |
| 312 | Description=Online ext4 Metadata Check for All Filesystems | |
| 313 | LoadState=loaded | |
| 314 | ActiveState=inactive | |
| 315 | SubState=dead | |
| 316 | FragmentPath=/usr/lib/systemd/system/e2scrub_all.service | |
| 317 | UnitFileState=static | |
| 318 | ActiveEnterTimestamp= | |
| 319 | ||
| 320 | MainPID=0 | |
| 321 | User=root | |
| 322 | Id=e2scrub_reap.service | |
| 323 | Description=Remove Stale Online ext4 Metadata Check Snapshots | |
| 324 | LoadState=loaded | |
| 325 | ActiveState=inactive | |
| 326 | SubState=dead | |
| 327 | FragmentPath=/usr/lib/systemd/system/e2scrub_reap.service | |
| 328 | UnitFileState=enabled | |
| 329 | ActiveEnterTimestamp= | |
| 330 | ||
| 331 | MainPID=1011 | |
| 332 | User=fleeky | |
| 333 | Id=easynews-indexer.service | |
| 334 | Description=Easynews Indexer Bridge | |
| 335 | LoadState=loaded | |
| 336 | ActiveState=active | |
| 337 | SubState=running | |
| 338 | FragmentPath=/etc/systemd/system/easynews-indexer.service | |
| 339 | UnitFileState=enabled | |
| 340 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 341 | ||
| 342 | MainPID=0 | |
| 343 | User= | |
| 344 | Id=emergency.service | |
| 345 | Description=Emergency Shell | |
| 346 | LoadState=loaded | |
| 347 | ActiveState=inactive | |
| 348 | SubState=dead | |
| 349 | FragmentPath=/usr/lib/systemd/system/emergency.service | |
| 350 | UnitFileState=static | |
| 351 | ActiveEnterTimestamp= | |
| 352 | ||
| 353 | MainPID=0 | |
| 354 | User= | |
| 355 | Id=fcoe.service | |
| 356 | Description=fcoe.service | |
| 357 | LoadState=not-found | |
| 358 | ActiveState=inactive | |
| 359 | SubState=dead | |
| 360 | FragmentPath= | |
| 361 | UnitFileState= | |
| 362 | ActiveEnterTimestamp= | |
| 363 | ||
| 364 | MainPID=0 | |
| 365 | User= | |
| 366 | Id=finalrd.service | |
| 367 | Description=Create final runtime dir for shutdown pivot root | |
| 368 | LoadState=loaded | |
| 369 | ActiveState=active | |
| 370 | SubState=exited | |
| 371 | FragmentPath=/usr/lib/systemd/system/finalrd.service | |
| 372 | UnitFileState=enabled | |
| 373 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:00 EDT | |
| 374 | ||
| 375 | MainPID=0 | |
| 376 | User= | |
| 377 | Id=fstrim.service | |
| 378 | Description=Discard unused blocks on filesystems from /etc/fstab | |
| 379 | LoadState=loaded | |
| 380 | ActiveState=inactive | |
| 381 | SubState=dead | |
| 382 | FragmentPath=/usr/lib/systemd/system/fstrim.service | |
| 383 | UnitFileState=static | |
| 384 | ActiveEnterTimestamp= | |
| 385 | ||
| 386 | MainPID=0 | |
| 387 | User=fwupd-refresh | |
| 388 | Id=fwupd-refresh.service | |
| 389 | Description=Refresh fwupd metadata and update motd | |
| 390 | LoadState=loaded | |
| 391 | ActiveState=inactive | |
| 392 | SubState=dead | |
| 393 | FragmentPath=/usr/lib/systemd/system/fwupd-refresh.service | |
| 394 | UnitFileState=static | |
| 395 | ActiveEnterTimestamp= | |
| 396 | ||
| 397 | MainPID=11784 | |
| 398 | User= | |
| 399 | Id=fwupd.service | |
| 400 | Description=Firmware update daemon | |
| 401 | LoadState=loaded | |
| 402 | ActiveState=active | |
| 403 | SubState=running | |
| 404 | FragmentPath=/usr/lib/systemd/system/fwupd.service | |
| 405 | UnitFileState=static | |
| 406 | ActiveEnterTimestamp=Sat 2026-08-08 21:05:35 EDT | |
| 407 | ||
| 408 | MainPID=0 | |
| 409 | User= | |
| 410 | Id=getty-static.service | |
| 411 | Description=getty on tty2-tty6 if dbus and logind are not available | |
| 412 | LoadState=loaded | |
| 413 | ActiveState=inactive | |
| 414 | SubState=dead | |
| 415 | FragmentPath=/usr/lib/systemd/system/getty-static.service | |
| 416 | UnitFileState=static | |
| 417 | ActiveEnterTimestamp= | |
| 418 | ||
| 419 | MainPID=1032 | |
| 420 | User= | |
| 421 | Id=getty@tty1.service | |
| 422 | Description=Getty on tty1 | |
| 423 | LoadState=loaded | |
| 424 | ActiveState=active | |
| 425 | SubState=running | |
| 426 | FragmentPath=/usr/lib/systemd/system/getty@.service | |
| 427 | UnitFileState=enabled | |
| 428 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:25 EDT | |
| 429 | ||
| 430 | MainPID=1033 | |
| 431 | User= | |
| 432 | Id=getty@tty7.service | |
| 433 | Description=Getty on tty7 | |
| 434 | LoadState=loaded | |
| 435 | ActiveState=active | |
| 436 | SubState=running | |
| 437 | FragmentPath=/usr/lib/systemd/system/getty@.service | |
| 438 | UnitFileState=enabled | |
| 439 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:25 EDT | |
| 440 | ||
| 441 | MainPID=0 | |
| 442 | User= | |
| 443 | Id=gpu-manager.service | |
| 444 | Description=Detect the available GPUs and deal with any system changes | |
| 445 | LoadState=loaded | |
| 446 | ActiveState=inactive | |
| 447 | SubState=dead | |
| 448 | FragmentPath=/usr/lib/systemd/system/gpu-manager.service | |
| 449 | UnitFileState=enabled | |
| 450 | ActiveEnterTimestamp= | |
| 451 | ||
| 452 | MainPID=0 | |
| 453 | User= | |
| 454 | Id=grub-common.service | |
| 455 | Description=Record successful boot for GRUB | |
| 456 | LoadState=loaded | |
| 457 | ActiveState=inactive | |
| 458 | SubState=dead | |
| 459 | FragmentPath=/usr/lib/systemd/system/grub-common.service | |
| 460 | UnitFileState=enabled | |
| 461 | ActiveEnterTimestamp= | |
| 462 | ||
| 463 | MainPID=0 | |
| 464 | User= | |
| 465 | Id=grub-initrd-fallback.service | |
| 466 | Description=GRUB failed boot detection | |
| 467 | LoadState=loaded | |
| 468 | ActiveState=inactive | |
| 469 | SubState=dead | |
| 470 | FragmentPath=/usr/lib/systemd/system/grub-initrd-fallback.service | |
| 471 | UnitFileState=enabled | |
| 472 | ActiveEnterTimestamp= | |
| 473 | ||
| 474 | MainPID=1060 | |
| 475 | User=fleeky | |
| 476 | Id=hyperident-gateway.service | |
| 477 | Description=Hyperident P2P Gateway | |
| 478 | LoadState=loaded | |
| 479 | ActiveState=active | |
| 480 | SubState=running | |
| 481 | FragmentPath=/etc/systemd/system/hyperident-gateway.service | |
| 482 | UnitFileState=enabled | |
| 483 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:30 EDT | |
| 484 | ||
| 485 | MainPID=0 | |
| 486 | User= | |
| 487 | Id=initrd-cleanup.service | |
| 488 | Description=Cleaning Up and Shutting Down Daemons | |
| 489 | LoadState=loaded | |
| 490 | ActiveState=inactive | |
| 491 | SubState=dead | |
| 492 | FragmentPath=/usr/lib/systemd/system/initrd-cleanup.service | |
| 493 | UnitFileState=static | |
| 494 | ActiveEnterTimestamp= | |
| 495 | ||
| 496 | MainPID=0 | |
| 497 | User= | |
| 498 | Id=initrd-parse-etc.service | |
| 499 | Description=Mountpoints Configured in the Real Root | |
| 500 | LoadState=loaded | |
| 501 | ActiveState=inactive | |
| 502 | SubState=dead | |
| 503 | FragmentPath=/usr/lib/systemd/system/initrd-parse-etc.service | |
| 504 | UnitFileState=static | |
| 505 | ActiveEnterTimestamp= | |
| 506 | ||
| 507 | MainPID=0 | |
| 508 | User= | |
| 509 | Id=initrd-switch-root.service | |
| 510 | Description=Switch Root | |
| 511 | LoadState=loaded | |
| 512 | ActiveState=inactive | |
| 513 | SubState=dead | |
| 514 | FragmentPath=/usr/lib/systemd/system/initrd-switch-root.service | |
| 515 | UnitFileState=static | |
| 516 | ActiveEnterTimestamp= | |
| 517 | ||
| 518 | MainPID=0 | |
| 519 | User= | |
| 520 | Id=initrd-udevadm-cleanup-db.service | |
| 521 | Description=Cleanup udev Database | |
| 522 | LoadState=loaded | |
| 523 | ActiveState=inactive | |
| 524 | SubState=dead | |
| 525 | FragmentPath=/usr/lib/systemd/system/initrd-udevadm-cleanup-db.service | |
| 526 | UnitFileState=static | |
| 527 | ActiveEnterTimestamp= | |
| 528 | ||
| 529 | MainPID=781 | |
| 530 | User= | |
| 531 | Id=irqbalance.service | |
| 532 | Description=irqbalance daemon | |
| 533 | LoadState=loaded | |
| 534 | ActiveState=active | |
| 535 | SubState=running | |
| 536 | FragmentPath=/usr/lib/systemd/system/irqbalance.service | |
| 537 | UnitFileState=enabled | |
| 538 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:08 EDT | |
| 539 | ||
| 540 | MainPID=0 | |
| 541 | User= | |
| 542 | Id=iscsi-shutdown.service | |
| 543 | Description=iscsi-shutdown.service | |
| 544 | LoadState=not-found | |
| 545 | ActiveState=inactive | |
| 546 | SubState=dead | |
| 547 | FragmentPath= | |
| 548 | UnitFileState= | |
| 549 | ActiveEnterTimestamp= | |
| 550 | ||
| 551 | MainPID=0 | |
| 552 | User= | |
| 553 | Id=iscsi.service | |
| 554 | Description=iscsi.service | |
| 555 | LoadState=not-found | |
| 556 | ActiveState=inactive | |
| 557 | SubState=dead | |
| 558 | FragmentPath= | |
| 559 | UnitFileState= | |
| 560 | ActiveEnterTimestamp= | |
| 561 | ||
| 562 | MainPID=0 | |
| 563 | User= | |
| 564 | Id=iscsid.service | |
| 565 | Description=iscsid.service | |
| 566 | LoadState=not-found | |
| 567 | ActiveState=inactive | |
| 568 | SubState=dead | |
| 569 | FragmentPath= | |
| 570 | UnitFileState= | |
| 571 | ActiveEnterTimestamp= | |
| 572 | ||
| 573 | MainPID=1071 | |
| 574 | User=jellyfin | |
| 575 | Id=jellyfin.service | |
| 576 | Description=Jellyfin Media Server | |
| 577 | LoadState=loaded | |
| 578 | ActiveState=active | |
| 579 | SubState=running | |
| 580 | FragmentPath=/usr/lib/systemd/system/jellyfin.service | |
| 581 | UnitFileState=enabled | |
| 582 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:31 EDT | |
| 583 | ||
| 584 | MainPID=1012 | |
| 585 | User=fleeky | |
| 586 | Id=jellyseerr.service | |
| 587 | Description=Jellyseerr | |
| 588 | LoadState=loaded | |
| 589 | ActiveState=active | |
| 590 | SubState=running | |
| 591 | FragmentPath=/etc/systemd/system/jellyseerr.service | |
| 592 | UnitFileState=enabled | |
| 593 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 594 | ||
| 595 | MainPID=0 | |
| 596 | User= | |
| 597 | Id=kbd.service | |
| 598 | Description=kbd.service | |
| 599 | LoadState=not-found | |
| 600 | ActiveState=inactive | |
| 601 | SubState=dead | |
| 602 | FragmentPath= | |
| 603 | UnitFileState= | |
| 604 | ActiveEnterTimestamp= | |
| 605 | ||
| 606 | MainPID=0 | |
| 607 | User=kernoops | |
| 608 | Id=kerneloops.service | |
| 609 | Description=Tool to automatically collect and submit kernel crash signatures | |
| 610 | LoadState=loaded | |
| 611 | ActiveState=active | |
| 612 | SubState=running | |
| 613 | FragmentPath=/usr/lib/systemd/system/kerneloops.service | |
| 614 | UnitFileState=enabled | |
| 615 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:31 EDT | |
| 616 | ||
| 617 | MainPID=0 | |
| 618 | User= | |
| 619 | Id=keyboard-setup.service | |
| 620 | Description=Set the console keyboard layout | |
| 621 | LoadState=loaded | |
| 622 | ActiveState=active | |
| 623 | SubState=exited | |
| 624 | FragmentPath=/usr/lib/systemd/system/keyboard-setup.service | |
| 625 | UnitFileState=enabled | |
| 626 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:47 EDT | |
| 627 | ||
| 628 | MainPID=0 | |
| 629 | User= | |
| 630 | Id=kmod-static-nodes.service | |
| 631 | Description=Create List of Static Device Nodes | |
| 632 | LoadState=loaded | |
| 633 | ActiveState=active | |
| 634 | SubState=exited | |
| 635 | FragmentPath=/usr/lib/systemd/system/kmod-static-nodes.service | |
| 636 | UnitFileState=static | |
| 637 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:46 EDT | |
| 638 | ||
| 639 | MainPID=0 | |
| 640 | User= | |
| 641 | Id=ldconfig.service | |
| 642 | Description=Rebuild Dynamic Linker Cache | |
| 643 | LoadState=loaded | |
| 644 | ActiveState=inactive | |
| 645 | SubState=dead | |
| 646 | FragmentPath=/usr/lib/systemd/system/ldconfig.service | |
| 647 | UnitFileState=static | |
| 648 | ActiveEnterTimestamp= | |
| 649 | ||
| 650 | MainPID=0 | |
| 651 | User= | |
| 652 | Id=lightdm.service | |
| 653 | Description=Light Display Manager | |
| 654 | LoadState=loaded | |
| 655 | ActiveState=inactive | |
| 656 | SubState=dead | |
| 657 | FragmentPath=/usr/lib/systemd/system/lightdm.service | |
| 658 | UnitFileState=indirect | |
| 659 | ActiveEnterTimestamp= | |
| 660 | ||
| 661 | MainPID=0 | |
| 662 | User= | |
| 663 | Id=lm-sensors.service | |
| 664 | Description=Initialize hardware monitoring sensors | |
| 665 | LoadState=loaded | |
| 666 | ActiveState=active | |
| 667 | SubState=exited | |
| 668 | FragmentPath=/usr/lib/systemd/system/lm-sensors.service | |
| 669 | UnitFileState=enabled | |
| 670 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:10 EDT | |
| 671 | ||
| 672 | MainPID=0 | |
| 673 | User= | |
| 674 | Id=logrotate.service | |
| 675 | Description=Rotate log files | |
| 676 | LoadState=loaded | |
| 677 | ActiveState=inactive | |
| 678 | SubState=dead | |
| 679 | FragmentPath=/usr/lib/systemd/system/logrotate.service | |
| 680 | UnitFileState=static | |
| 681 | ActiveEnterTimestamp= | |
| 682 | ||
| 683 | MainPID=0 | |
| 684 | User= | |
| 685 | Id=lvm2-lvmpolld.service | |
| 686 | Description=LVM2 poll daemon | |
| 687 | LoadState=loaded | |
| 688 | ActiveState=inactive | |
| 689 | SubState=dead | |
| 690 | FragmentPath=/usr/lib/systemd/system/lvm2-lvmpolld.service | |
| 691 | UnitFileState=static | |
| 692 | ActiveEnterTimestamp= | |
| 693 | ||
| 694 | MainPID=0 | |
| 695 | User= | |
| 696 | Id=lvm2-monitor.service | |
| 697 | Description=Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling | |
| 698 | LoadState=loaded | |
| 699 | ActiveState=active | |
| 700 | SubState=exited | |
| 701 | FragmentPath=/usr/lib/systemd/system/lvm2-monitor.service | |
| 702 | UnitFileState=enabled | |
| 703 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:51 EDT | |
| 704 | ||
| 705 | MainPID=0 | |
| 706 | User=man | |
| 707 | Id=man-db.service | |
| 708 | Description=Daily man-db regeneration | |
| 709 | LoadState=loaded | |
| 710 | ActiveState=inactive | |
| 711 | SubState=dead | |
| 712 | FragmentPath=/usr/lib/systemd/system/man-db.service | |
| 713 | UnitFileState=static | |
| 714 | ActiveEnterTimestamp= | |
| 715 | ||
| 716 | MainPID=0 | |
| 717 | User= | |
| 718 | Id=mintsystem.service | |
| 719 | Description=mintsystem.service | |
| 720 | LoadState=loaded | |
| 721 | ActiveState=inactive | |
| 722 | SubState=dead | |
| 723 | FragmentPath=/usr/lib/systemd/system/mintsystem.service | |
| 724 | UnitFileState=enabled | |
| 725 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:08 EDT | |
| 726 | ||
| 727 | MainPID=918 | |
| 728 | User=root | |
| 729 | Id=ModemManager.service | |
| 730 | Description=Modem Manager | |
| 731 | LoadState=loaded | |
| 732 | ActiveState=active | |
| 733 | SubState=running | |
| 734 | FragmentPath=/usr/lib/systemd/system/ModemManager.service | |
| 735 | UnitFileState=enabled | |
| 736 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:16 EDT | |
| 737 | ||
| 738 | MainPID=0 | |
| 739 | User= | |
| 740 | Id=modprobe@configfs.service | |
| 741 | Description=Load Kernel Module configfs | |
| 742 | LoadState=loaded | |
| 743 | ActiveState=inactive | |
| 744 | SubState=dead | |
| 745 | FragmentPath=/usr/lib/systemd/system/modprobe@.service | |
| 746 | UnitFileState=static | |
| 747 | ActiveEnterTimestamp= | |
| 748 | ||
| 749 | MainPID=0 | |
| 750 | User= | |
| 751 | Id=modprobe@dm_mod.service | |
| 752 | Description=Load Kernel Module dm_mod | |
| 753 | LoadState=loaded | |
| 754 | ActiveState=inactive | |
| 755 | SubState=dead | |
| 756 | FragmentPath=/usr/lib/systemd/system/modprobe@.service | |
| 757 | UnitFileState=static | |
| 758 | ActiveEnterTimestamp= | |
| 759 | ||
| 760 | MainPID=0 | |
| 761 | User= | |
| 762 | Id=modprobe@drm.service | |
| 763 | Description=Load Kernel Module drm | |
| 764 | LoadState=loaded | |
| 765 | ActiveState=inactive | |
| 766 | SubState=dead | |
| 767 | FragmentPath=/usr/lib/systemd/system/modprobe@.service | |
| 768 | UnitFileState=static | |
| 769 | ActiveEnterTimestamp= | |
| 770 | ||
| 771 | MainPID=0 | |
| 772 | User= | |
| 773 | Id=modprobe@efi_pstore.service | |
| 774 | Description=Load Kernel Module efi_pstore | |
| 775 | LoadState=loaded | |
| 776 | ActiveState=inactive | |
| 777 | SubState=dead | |
| 778 | FragmentPath=/usr/lib/systemd/system/modprobe@.service | |
| 779 | UnitFileState=static | |
| 780 | ActiveEnterTimestamp= | |
| 781 | ||
| 782 | MainPID=0 | |
| 783 | User= | |
| 784 | Id=modprobe@fuse.service | |
| 785 | Description=Load Kernel Module fuse | |
| 786 | LoadState=loaded | |
| 787 | ActiveState=inactive | |
| 788 | SubState=dead | |
| 789 | FragmentPath=/usr/lib/systemd/system/modprobe@.service | |
| 790 | UnitFileState=static | |
| 791 | ActiveEnterTimestamp= | |
| 792 | ||
| 793 | MainPID=0 | |
| 794 | User= | |
| 795 | Id=modprobe@loop.service | |
| 796 | Description=Load Kernel Module loop | |
| 797 | LoadState=loaded | |
| 798 | ActiveState=inactive | |
| 799 | SubState=dead | |
| 800 | FragmentPath=/usr/lib/systemd/system/modprobe@.service | |
| 801 | UnitFileState=static | |
| 802 | ActiveEnterTimestamp= | |
| 803 | ||
| 804 | MainPID=0 | |
| 805 | User= | |
| 806 | Id=motd-news.service | |
| 807 | Description=Message of the Day | |
| 808 | LoadState=loaded | |
| 809 | ActiveState=inactive | |
| 810 | SubState=dead | |
| 811 | FragmentPath=/usr/lib/systemd/system/motd-news.service | |
| 812 | UnitFileState=static | |
| 813 | ActiveEnterTimestamp= | |
| 814 | ||
| 815 | MainPID=0 | |
| 816 | User= | |
| 817 | Id=netplan-ovs-cleanup.service | |
| 818 | Description=OpenVSwitch configuration for cleanup | |
| 819 | LoadState=loaded | |
| 820 | ActiveState=inactive | |
| 821 | SubState=dead | |
| 822 | FragmentPath=/run/systemd/system/netplan-ovs-cleanup.service | |
| 823 | UnitFileState=enabled-runtime | |
| 824 | ActiveEnterTimestamp= | |
| 825 | ||
| 826 | MainPID=0 | |
| 827 | User= | |
| 828 | Id=network-manager.service | |
| 829 | Description=network-manager.service | |
| 830 | LoadState=not-found | |
| 831 | ActiveState=inactive | |
| 832 | SubState=dead | |
| 833 | FragmentPath= | |
| 834 | UnitFileState= | |
| 835 | ActiveEnterTimestamp= | |
| 836 | ||
| 837 | MainPID=0 | |
| 838 | User= | |
| 839 | Id=networkd-dispatcher.service | |
| 840 | Description=Dispatcher daemon for systemd-networkd | |
| 841 | LoadState=loaded | |
| 842 | ActiveState=inactive | |
| 843 | SubState=dead | |
| 844 | FragmentPath=/usr/lib/systemd/system/networkd-dispatcher.service | |
| 845 | UnitFileState=enabled | |
| 846 | ActiveEnterTimestamp= | |
| 847 | ||
| 848 | MainPID=0 | |
| 849 | User= | |
| 850 | Id=NetworkManager-wait-online.service | |
| 851 | Description=Network Manager Wait Online | |
| 852 | LoadState=loaded | |
| 853 | ActiveState=active | |
| 854 | SubState=exited | |
| 855 | FragmentPath=/usr/lib/systemd/system/NetworkManager-wait-online.service | |
| 856 | UnitFileState=enabled | |
| 857 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:30 EDT | |
| 858 | ||
| 859 | MainPID=887 | |
| 860 | User= | |
| 861 | Id=NetworkManager.service | |
| 862 | Description=Network Manager | |
| 863 | LoadState=loaded | |
| 864 | ActiveState=active | |
| 865 | SubState=running | |
| 866 | FragmentPath=/usr/lib/systemd/system/NetworkManager.service | |
| 867 | UnitFileState=enabled | |
| 868 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 869 | ||
| 870 | MainPID=0 | |
| 871 | User= | |
| 872 | Id=nslcd.service | |
| 873 | Description=nslcd.service | |
| 874 | LoadState=not-found | |
| 875 | ActiveState=inactive | |
| 876 | SubState=dead | |
| 877 | FragmentPath= | |
| 878 | UnitFileState= | |
| 879 | ActiveEnterTimestamp= | |
| 880 | ||
| 881 | MainPID=0 | |
| 882 | User= | |
| 883 | Id=oem-config.service | |
| 884 | Description=oem-config.service | |
| 885 | LoadState=not-found | |
| 886 | ActiveState=inactive | |
| 887 | SubState=dead | |
| 888 | FragmentPath= | |
| 889 | UnitFileState= | |
| 890 | ActiveEnterTimestamp= | |
| 891 | ||
| 892 | MainPID=0 | |
| 893 | User= | |
| 894 | Id=openvpn.service | |
| 895 | Description=OpenVPN service | |
| 896 | LoadState=loaded | |
| 897 | ActiveState=active | |
| 898 | SubState=exited | |
| 899 | FragmentPath=/usr/lib/systemd/system/openvpn.service | |
| 900 | UnitFileState=enabled | |
| 901 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 902 | ||
| 903 | MainPID=0 | |
| 904 | User= | |
| 905 | Id=ovsdb-server.service | |
| 906 | Description=ovsdb-server.service | |
| 907 | LoadState=not-found | |
| 908 | ActiveState=inactive | |
| 909 | SubState=dead | |
| 910 | FragmentPath= | |
| 911 | UnitFileState= | |
| 912 | ActiveEnterTimestamp= | |
| 913 | ||
| 914 | MainPID=1081 | |
| 915 | User=plex | |
| 916 | Id=plexmediaserver.service | |
| 917 | Description=Plex Media Server | |
| 918 | LoadState=loaded | |
| 919 | ActiveState=active | |
| 920 | SubState=running | |
| 921 | FragmentPath=/usr/lib/systemd/system/plexmediaserver.service | |
| 922 | UnitFileState=enabled | |
| 923 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:31 EDT | |
| 924 | ||
| 925 | MainPID=0 | |
| 926 | User= | |
| 927 | Id=plocate-updatedb.service | |
| 928 | Description=Update the plocate database | |
| 929 | LoadState=loaded | |
| 930 | ActiveState=inactive | |
| 931 | SubState=dead | |
| 932 | FragmentPath=/usr/lib/systemd/system/plocate-updatedb.service | |
| 933 | UnitFileState=static | |
| 934 | ActiveEnterTimestamp= | |
| 935 | ||
| 936 | MainPID=0 | |
| 937 | User= | |
| 938 | Id=plymouth-halt.service | |
| 939 | Description=Show Plymouth Halt Screen | |
| 940 | LoadState=loaded | |
| 941 | ActiveState=inactive | |
| 942 | SubState=dead | |
| 943 | FragmentPath=/usr/lib/systemd/system/plymouth-halt.service | |
| 944 | UnitFileState=static | |
| 945 | ActiveEnterTimestamp= | |
| 946 | ||
| 947 | MainPID=0 | |
| 948 | User= | |
| 949 | Id=plymouth-poweroff.service | |
| 950 | Description=Show Plymouth Power Off Screen | |
| 951 | LoadState=loaded | |
| 952 | ActiveState=inactive | |
| 953 | SubState=dead | |
| 954 | FragmentPath=/usr/lib/systemd/system/plymouth-poweroff.service | |
| 955 | UnitFileState=static | |
| 956 | ActiveEnterTimestamp= | |
| 957 | ||
| 958 | MainPID=0 | |
| 959 | User= | |
| 960 | Id=plymouth-quit-wait.service | |
| 961 | Description=Hold until boot process finishes up | |
| 962 | LoadState=loaded | |
| 963 | ActiveState=active | |
| 964 | SubState=exited | |
| 965 | FragmentPath=/usr/lib/systemd/system/plymouth-quit-wait.service | |
| 966 | UnitFileState=static | |
| 967 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 968 | ||
| 969 | MainPID=0 | |
| 970 | User= | |
| 971 | Id=plymouth-quit.service | |
| 972 | Description=Terminate Plymouth Boot Screen | |
| 973 | LoadState=loaded | |
| 974 | ActiveState=active | |
| 975 | SubState=exited | |
| 976 | FragmentPath=/usr/lib/systemd/system/plymouth-quit.service | |
| 977 | UnitFileState=static | |
| 978 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 979 | ||
| 980 | MainPID=0 | |
| 981 | User= | |
| 982 | Id=plymouth-read-write.service | |
| 983 | Description=Tell Plymouth To Write Out Runtime Data | |
| 984 | LoadState=loaded | |
| 985 | ActiveState=active | |
| 986 | SubState=exited | |
| 987 | FragmentPath=/usr/lib/systemd/system/plymouth-read-write.service | |
| 988 | UnitFileState=static | |
| 989 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:00 EDT | |
| 990 | ||
| 991 | MainPID=0 | |
| 992 | User= | |
| 993 | Id=plymouth-reboot.service | |
| 994 | Description=Show Plymouth Reboot Screen | |
| 995 | LoadState=loaded | |
| 996 | ActiveState=inactive | |
| 997 | SubState=dead | |
| 998 | FragmentPath=/usr/lib/systemd/system/plymouth-reboot.service | |
| 999 | UnitFileState=static | |
| 1000 | ActiveEnterTimestamp= | |
| 1001 | ||
| 1002 | MainPID=0 | |
| 1003 | User= | |
| 1004 | Id=plymouth-start.service | |
| 1005 | Description=Show Plymouth Boot Screen | |
| 1006 | LoadState=loaded | |
| 1007 | ActiveState=active | |
| 1008 | SubState=exited | |
| 1009 | FragmentPath=/usr/lib/systemd/system/plymouth-start.service | |
| 1010 | UnitFileState=static | |
| 1011 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:56 EDT | |
| 1012 | ||
| 1013 | MainPID=0 | |
| 1014 | User= | |
| 1015 | Id=plymouth-switch-root.service | |
| 1016 | Description=Plymouth switch root service | |
| 1017 | LoadState=loaded | |
| 1018 | ActiveState=inactive | |
| 1019 | SubState=dead | |
| 1020 | FragmentPath=/usr/lib/systemd/system/plymouth-switch-root.service | |
| 1021 | UnitFileState=static | |
| 1022 | ActiveEnterTimestamp= | |
| 1023 | ||
| 1024 | MainPID=785 | |
| 1025 | User=polkitd | |
| 1026 | Id=polkit.service | |
| 1027 | Description=Authorization Manager | |
| 1028 | LoadState=loaded | |
| 1029 | ActiveState=active | |
| 1030 | SubState=running | |
| 1031 | FragmentPath=/usr/lib/systemd/system/polkit.service | |
| 1032 | UnitFileState=static | |
| 1033 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:13 EDT | |
| 1034 | ||
| 1035 | MainPID=0 | |
| 1036 | User= | |
| 1037 | Id=power-profiles-daemon.service | |
| 1038 | Description=Power Profiles daemon | |
| 1039 | LoadState=loaded | |
| 1040 | ActiveState=inactive | |
| 1041 | SubState=dead | |
| 1042 | FragmentPath=/usr/lib/systemd/system/power-profiles-daemon.service | |
| 1043 | UnitFileState=enabled | |
| 1044 | ActiveEnterTimestamp= | |
| 1045 | ||
| 1046 | MainPID=1014 | |
| 1047 | User=fleeky | |
| 1048 | Id=prowlarr.service | |
| 1049 | Description=Prowlarr Daemon | |
| 1050 | LoadState=loaded | |
| 1051 | ActiveState=active | |
| 1052 | SubState=running | |
| 1053 | FragmentPath=/etc/systemd/system/prowlarr.service | |
| 1054 | UnitFileState=enabled | |
| 1055 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 1056 | ||
| 1057 | MainPID=1015 | |
| 1058 | User=fleeky | |
| 1059 | Id=radarr.service | |
| 1060 | Description=Radarr Daemon | |
| 1061 | LoadState=loaded | |
| 1062 | ActiveState=active | |
| 1063 | SubState=running | |
| 1064 | FragmentPath=/etc/systemd/system/radarr.service | |
| 1065 | UnitFileState=enabled | |
| 1066 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 1067 | ||
| 1068 | MainPID=0 | |
| 1069 | User= | |
| 1070 | Id=rbdmap.service | |
| 1071 | Description=rbdmap.service | |
| 1072 | LoadState=not-found | |
| 1073 | ActiveState=inactive | |
| 1074 | SubState=dead | |
| 1075 | FragmentPath= | |
| 1076 | UnitFileState= | |
| 1077 | ActiveEnterTimestamp= | |
| 1078 | ||
| 1079 | MainPID=0 | |
| 1080 | User= | |
| 1081 | Id=rc-local.service | |
| 1082 | Description=/etc/rc.local Compatibility | |
| 1083 | LoadState=loaded | |
| 1084 | ActiveState=inactive | |
| 1085 | SubState=dead | |
| 1086 | FragmentPath=/usr/lib/systemd/system/rc-local.service | |
| 1087 | UnitFileState=static | |
| 1088 | ActiveEnterTimestamp= | |
| 1089 | ||
| 1090 | MainPID=0 | |
| 1091 | User= | |
| 1092 | Id=rescue.service | |
| 1093 | Description=Rescue Shell | |
| 1094 | LoadState=loaded | |
| 1095 | ActiveState=inactive | |
| 1096 | SubState=dead | |
| 1097 | FragmentPath=/usr/lib/systemd/system/rescue.service | |
| 1098 | UnitFileState=static | |
| 1099 | ActiveEnterTimestamp= | |
| 1100 | ||
| 1101 | MainPID=797 | |
| 1102 | User= | |
| 1103 | Id=rsyslog.service | |
| 1104 | Description=System Logging Service | |
| 1105 | LoadState=loaded | |
| 1106 | ActiveState=active | |
| 1107 | SubState=running | |
| 1108 | FragmentPath=/usr/lib/systemd/system/rsyslog.service | |
| 1109 | UnitFileState=enabled | |
| 1110 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:10 EDT | |
| 1111 | ||
| 1112 | MainPID=1264 | |
| 1113 | User= | |
| 1114 | Id=rtkit-daemon.service | |
| 1115 | Description=RealtimeKit Scheduling Policy Service | |
| 1116 | LoadState=loaded | |
| 1117 | ActiveState=active | |
| 1118 | SubState=running | |
| 1119 | FragmentPath=/usr/lib/systemd/system/rtkit-daemon.service | |
| 1120 | UnitFileState=disabled | |
| 1121 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:19 EDT | |
| 1122 | ||
| 1123 | MainPID=0 | |
| 1124 | User= | |
| 1125 | Id=sabnzbdplus.service | |
| 1126 | Description=LSB: SABnzbd+ binary newsgrabber | |
| 1127 | LoadState=loaded | |
| 1128 | ActiveState=active | |
| 1129 | SubState=running | |
| 1130 | FragmentPath=/run/systemd/generator.late/sabnzbdplus.service | |
| 1131 | UnitFileState=generated | |
| 1132 | ActiveEnterTimestamp=Sat 2026-08-08 20:27:09 EDT | |
| 1133 | ||
| 1134 | MainPID=0 | |
| 1135 | User= | |
| 1136 | Id=secureboot-db.service | |
| 1137 | Description=Secure Boot updates for DB and DBX | |
| 1138 | LoadState=loaded | |
| 1139 | ActiveState=inactive | |
| 1140 | SubState=dead | |
| 1141 | FragmentPath=/usr/lib/systemd/system/secureboot-db.service | |
| 1142 | UnitFileState=enabled | |
| 1143 | ActiveEnterTimestamp= | |
| 1144 | ||
| 1145 | MainPID=0 | |
| 1146 | User= | |
| 1147 | Id=setvtrgb.service | |
| 1148 | Description=Set console scheme | |
| 1149 | LoadState=loaded | |
| 1150 | ActiveState=active | |
| 1151 | SubState=exited | |
| 1152 | FragmentPath=/usr/lib/systemd/system/setvtrgb.service | |
| 1153 | UnitFileState=enabled | |
| 1154 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:25 EDT | |
| 1155 | ||
| 1156 | MainPID=790 | |
| 1157 | User= | |
| 1158 | Id=smartmontools.service | |
| 1159 | Description=Self Monitoring and Reporting Technology (SMART) Daemon | |
| 1160 | LoadState=loaded | |
| 1161 | ActiveState=active | |
| 1162 | SubState=running | |
| 1163 | FragmentPath=/usr/lib/systemd/system/smartmontools.service | |
| 1164 | UnitFileState=enabled | |
| 1165 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:28 EDT | |
| 1166 | ||
| 1167 | MainPID=1016 | |
| 1168 | User=fleeky | |
| 1169 | Id=sonarr.service | |
| 1170 | Description=Sonarr Daemon | |
| 1171 | LoadState=loaded | |
| 1172 | ActiveState=active | |
| 1173 | SubState=running | |
| 1174 | FragmentPath=/etc/systemd/system/sonarr.service | |
| 1175 | UnitFileState=enabled | |
| 1176 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 1177 | ||
| 1178 | MainPID=1142 | |
| 1179 | User= | |
| 1180 | Id=ssh.service | |
| 1181 | Description=OpenBSD Secure Shell server | |
| 1182 | LoadState=loaded | |
| 1183 | ActiveState=active | |
| 1184 | SubState=running | |
| 1185 | FragmentPath=/usr/lib/systemd/system/ssh.service | |
| 1186 | UnitFileState=disabled | |
| 1187 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:45 EDT | |
| 1188 | ||
| 1189 | MainPID=0 | |
| 1190 | User= | |
| 1191 | Id=ssl-cert.service | |
| 1192 | Description=Generate snakeoil SSL keypair | |
| 1193 | LoadState=loaded | |
| 1194 | ActiveState=inactive | |
| 1195 | SubState=dead | |
| 1196 | FragmentPath=/usr/lib/systemd/system/ssl-cert.service | |
| 1197 | UnitFileState=enabled | |
| 1198 | ActiveEnterTimestamp= | |
| 1199 | ||
| 1200 | MainPID=0 | |
| 1201 | User= | |
| 1202 | Id=switcheroo-control.service | |
| 1203 | Description=Switcheroo Control Proxy service | |
| 1204 | LoadState=loaded | |
| 1205 | ActiveState=inactive | |
| 1206 | SubState=dead | |
| 1207 | FragmentPath=/usr/lib/systemd/system/switcheroo-control.service | |
| 1208 | UnitFileState=enabled | |
| 1209 | ActiveEnterTimestamp= | |
| 1210 | ||
| 1211 | MainPID=0 | |
| 1212 | User= | |
| 1213 | Id=system76-power.service | |
| 1214 | Description=system76-power.service | |
| 1215 | LoadState=not-found | |
| 1216 | ActiveState=inactive | |
| 1217 | SubState=dead | |
| 1218 | FragmentPath= | |
| 1219 | UnitFileState= | |
| 1220 | ActiveEnterTimestamp= | |
| 1221 | ||
| 1222 | MainPID=0 | |
| 1223 | User= | |
| 1224 | Id=systemd-ask-password-console.service | |
| 1225 | Description=Dispatch Password Requests to Console | |
| 1226 | LoadState=loaded | |
| 1227 | ActiveState=inactive | |
| 1228 | SubState=dead | |
| 1229 | FragmentPath=/usr/lib/systemd/system/systemd-ask-password-console.service | |
| 1230 | UnitFileState=static | |
| 1231 | ActiveEnterTimestamp= | |
| 1232 | ||
| 1233 | MainPID=0 | |
| 1234 | User= | |
| 1235 | Id=systemd-ask-password-plymouth.service | |
| 1236 | Description=Forward Password Requests to Plymouth | |
| 1237 | LoadState=loaded | |
| 1238 | ActiveState=inactive | |
| 1239 | SubState=dead | |
| 1240 | FragmentPath=/usr/lib/systemd/system/systemd-ask-password-plymouth.service | |
| 1241 | UnitFileState=static | |
| 1242 | ActiveEnterTimestamp= | |
| 1243 | ||
| 1244 | MainPID=0 | |
| 1245 | User= | |
| 1246 | Id=systemd-ask-password-wall.service | |
| 1247 | Description=Forward Password Requests to Wall | |
| 1248 | LoadState=loaded | |
| 1249 | ActiveState=inactive | |
| 1250 | SubState=dead | |
| 1251 | FragmentPath=/usr/lib/systemd/system/systemd-ask-password-wall.service | |
| 1252 | UnitFileState=static | |
| 1253 | ActiveEnterTimestamp= | |
| 1254 | ||
| 1255 | MainPID=0 | |
| 1256 | User= | |
| 1257 | Id=systemd-battery-check.service | |
| 1258 | Description=Check battery level during early boot | |
| 1259 | LoadState=loaded | |
| 1260 | ActiveState=inactive | |
| 1261 | SubState=dead | |
| 1262 | FragmentPath=/usr/lib/systemd/system/systemd-battery-check.service | |
| 1263 | UnitFileState=static | |
| 1264 | ActiveEnterTimestamp= | |
| 1265 | ||
| 1266 | MainPID=0 | |
| 1267 | User= | |
| 1268 | Id=systemd-binfmt.service | |
| 1269 | Description=Set Up Additional Binary Formats | |
| 1270 | LoadState=loaded | |
| 1271 | ActiveState=active | |
| 1272 | SubState=exited | |
| 1273 | FragmentPath=/usr/lib/systemd/system/systemd-binfmt.service | |
| 1274 | UnitFileState=static | |
| 1275 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:00 EDT | |
| 1276 | ||
| 1277 | MainPID=0 | |
| 1278 | User= | |
| 1279 | Id=systemd-bsod.service | |
| 1280 | Description=Displays emergency message in full screen. | |
| 1281 | LoadState=loaded | |
| 1282 | ActiveState=inactive | |
| 1283 | SubState=dead | |
| 1284 | FragmentPath=/usr/lib/systemd/system/systemd-bsod.service | |
| 1285 | UnitFileState=static | |
| 1286 | ActiveEnterTimestamp= | |
| 1287 | ||
| 1288 | MainPID=0 | |
| 1289 | User= | |
| 1290 | Id=systemd-coredump@883-3308187-0.service | |
| 1291 | Description=Process Core Dump (PID 3308187/UID 0) | |
| 1292 | LoadState=loaded | |
| 1293 | ActiveState=failed | |
| 1294 | SubState=failed | |
| 1295 | FragmentPath=/usr/lib/systemd/system/systemd-coredump@.service | |
| 1296 | UnitFileState=static | |
| 1297 | ActiveEnterTimestamp=Mon 2026-09-07 15:54:17 EDT | |
| 1298 | ||
| 1299 | MainPID=0 | |
| 1300 | User= | |
| 1301 | Id=systemd-coredump@884-1768591-0.service | |
| 1302 | Description=Process Core Dump (PID 1768591/UID 0) | |
| 1303 | LoadState=loaded | |
| 1304 | ActiveState=failed | |
| 1305 | SubState=failed | |
| 1306 | FragmentPath=/usr/lib/systemd/system/systemd-coredump@.service | |
| 1307 | UnitFileState=static | |
| 1308 | ActiveEnterTimestamp=Tue 2026-09-15 00:11:52 EDT | |
| 1309 | ||
| 1310 | MainPID=0 | |
| 1311 | User= | |
| 1312 | Id=systemd-coredump@885-1430075-0.service | |
| 1313 | Description=Process Core Dump (PID 1430075/UID 0) | |
| 1314 | LoadState=loaded | |
| 1315 | ActiveState=failed | |
| 1316 | SubState=failed | |
| 1317 | FragmentPath=/usr/lib/systemd/system/systemd-coredump@.service | |
| 1318 | UnitFileState=static | |
| 1319 | ActiveEnterTimestamp=Tue 2026-09-22 21:06:35 EDT | |
| 1320 | ||
| 1321 | MainPID=0 | |
| 1322 | User= | |
| 1323 | Id=systemd-coredump@886-1726789-0.service | |
| 1324 | Description=Process Core Dump (PID 1726789/UID 0) | |
| 1325 | LoadState=loaded | |
| 1326 | ActiveState=failed | |
| 1327 | SubState=failed | |
| 1328 | FragmentPath=/usr/lib/systemd/system/systemd-coredump@.service | |
| 1329 | UnitFileState=static | |
| 1330 | ActiveEnterTimestamp=Wed 2026-09-23 12:44:01 EDT | |
| 1331 | ||
| 1332 | MainPID=0 | |
| 1333 | User= | |
| 1334 | Id=systemd-firstboot.service | |
| 1335 | Description=First Boot Wizard | |
| 1336 | LoadState=loaded | |
| 1337 | ActiveState=inactive | |
| 1338 | SubState=dead | |
| 1339 | FragmentPath=/usr/lib/systemd/system/systemd-firstboot.service | |
| 1340 | UnitFileState=static | |
| 1341 | ActiveEnterTimestamp= | |
| 1342 | ||
| 1343 | MainPID=0 | |
| 1344 | User= | |
| 1345 | Id=systemd-fsck-root.service | |
| 1346 | Description=File System Check on Root Device | |
| 1347 | LoadState=loaded | |
| 1348 | ActiveState=inactive | |
| 1349 | SubState=dead | |
| 1350 | FragmentPath=/usr/lib/systemd/system/systemd-fsck-root.service | |
| 1351 | UnitFileState=enabled-runtime | |
| 1352 | ActiveEnterTimestamp= | |
| 1353 | ||
| 1354 | MainPID=0 | |
| 1355 | User= | |
| 1356 | Id=systemd-fsck@dev-disk-by\x2duuid-BA88\x2d8C53.service | |
| 1357 | Description=File System Check on /dev/disk/by-uuid/BA88-8C53 | |
| 1358 | LoadState=loaded | |
| 1359 | ActiveState=active | |
| 1360 | SubState=exited | |
| 1361 | FragmentPath=/usr/lib/systemd/system/systemd-fsck@.service | |
| 1362 | UnitFileState=static | |
| 1363 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:00 EDT | |
| 1364 | ||
| 1365 | MainPID=0 | |
| 1366 | User= | |
| 1367 | Id=systemd-fsck@dev-disk-by\x2duuid-e146b8c4\x2df50b\x2d45c3\x2d8a8e\x2d9ae4c68dfca2.service | |
| 1368 | Description=File System Check on /dev/disk/by-uuid/e146b8c4-f50b-45c3-8a8e-9ae4c68dfca2 | |
| 1369 | LoadState=loaded | |
| 1370 | ActiveState=active | |
| 1371 | SubState=exited | |
| 1372 | FragmentPath=/usr/lib/systemd/system/systemd-fsck@.service | |
| 1373 | UnitFileState=static | |
| 1374 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:00 EDT | |
| 1375 | ||
| 1376 | MainPID=0 | |
| 1377 | User= | |
| 1378 | Id=systemd-fsckd.service | |
| 1379 | Description=File System Check Daemon to report status | |
| 1380 | LoadState=loaded | |
| 1381 | ActiveState=inactive | |
| 1382 | SubState=dead | |
| 1383 | FragmentPath=/usr/lib/systemd/system/systemd-fsckd.service | |
| 1384 | UnitFileState=static | |
| 1385 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:58 EDT | |
| 1386 | ||
| 1387 | MainPID=0 | |
| 1388 | User= | |
| 1389 | Id=systemd-halt.service | |
| 1390 | Description=System Halt | |
| 1391 | LoadState=loaded | |
| 1392 | ActiveState=inactive | |
| 1393 | SubState=dead | |
| 1394 | FragmentPath=/usr/lib/systemd/system/systemd-halt.service | |
| 1395 | UnitFileState=static | |
| 1396 | ActiveEnterTimestamp= | |
| 1397 | ||
| 1398 | MainPID=0 | |
| 1399 | User= | |
| 1400 | Id=systemd-hibernate-resume.service | |
| 1401 | Description=Resume from hibernation | |
| 1402 | LoadState=loaded | |
| 1403 | ActiveState=inactive | |
| 1404 | SubState=dead | |
| 1405 | FragmentPath=/usr/lib/systemd/system/systemd-hibernate-resume.service | |
| 1406 | UnitFileState=static | |
| 1407 | ActiveEnterTimestamp= | |
| 1408 | ||
| 1409 | MainPID=0 | |
| 1410 | User= | |
| 1411 | Id=systemd-hibernate.service | |
| 1412 | Description=System Hibernate | |
| 1413 | LoadState=loaded | |
| 1414 | ActiveState=inactive | |
| 1415 | SubState=dead | |
| 1416 | FragmentPath=/usr/lib/systemd/system/systemd-hibernate.service | |
| 1417 | UnitFileState=static | |
| 1418 | ActiveEnterTimestamp= | |
| 1419 | ||
| 1420 | MainPID=0 | |
| 1421 | User= | |
| 1422 | Id=systemd-hwdb-update.service | |
| 1423 | Description=Rebuild Hardware Database | |
| 1424 | LoadState=loaded | |
| 1425 | ActiveState=inactive | |
| 1426 | SubState=dead | |
| 1427 | FragmentPath=/usr/lib/systemd/system/systemd-hwdb-update.service | |
| 1428 | UnitFileState=static | |
| 1429 | ActiveEnterTimestamp= | |
| 1430 | ||
| 1431 | MainPID=0 | |
| 1432 | User= | |
| 1433 | Id=systemd-hybrid-sleep.service | |
| 1434 | Description=System Hybrid Suspend+Hibernate | |
| 1435 | LoadState=loaded | |
| 1436 | ActiveState=inactive | |
| 1437 | SubState=dead | |
| 1438 | FragmentPath=/usr/lib/systemd/system/systemd-hybrid-sleep.service | |
| 1439 | UnitFileState=static | |
| 1440 | ActiveEnterTimestamp= | |
| 1441 | ||
| 1442 | MainPID=0 | |
| 1443 | User= | |
| 1444 | Id=systemd-initctl.service | |
| 1445 | Description=initctl Compatibility Daemon | |
| 1446 | LoadState=loaded | |
| 1447 | ActiveState=inactive | |
| 1448 | SubState=dead | |
| 1449 | FragmentPath=/usr/lib/systemd/system/systemd-initctl.service | |
| 1450 | UnitFileState=static | |
| 1451 | ActiveEnterTimestamp= | |
| 1452 | ||
| 1453 | MainPID=0 | |
| 1454 | User= | |
| 1455 | Id=systemd-journal-catalog-update.service | |
| 1456 | Description=Rebuild Journal Catalog | |
| 1457 | LoadState=loaded | |
| 1458 | ActiveState=inactive | |
| 1459 | SubState=dead | |
| 1460 | FragmentPath=/usr/lib/systemd/system/systemd-journal-catalog-update.service | |
| 1461 | UnitFileState=static | |
| 1462 | ActiveEnterTimestamp= | |
| 1463 | ||
| 1464 | MainPID=0 | |
| 1465 | User= | |
| 1466 | Id=systemd-journal-flush.service | |
| 1467 | Description=Flush Journal to Persistent Storage | |
| 1468 | LoadState=loaded | |
| 1469 | ActiveState=active | |
| 1470 | SubState=exited | |
| 1471 | FragmentPath=/usr/lib/systemd/system/systemd-journal-flush.service | |
| 1472 | UnitFileState=static | |
| 1473 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:03 EDT | |
| 1474 | ||
| 1475 | MainPID=3814529 | |
| 1476 | User= | |
| 1477 | Id=systemd-journald.service | |
| 1478 | Description=Journal Service | |
| 1479 | LoadState=loaded | |
| 1480 | ActiveState=active | |
| 1481 | SubState=running | |
| 1482 | FragmentPath=/usr/lib/systemd/system/systemd-journald.service | |
| 1483 | UnitFileState=static | |
| 1484 | ActiveEnterTimestamp=Wed 2026-10-07 08:04:33 EDT | |
| 1485 | ||
| 1486 | MainPID=792 | |
| 1487 | User= | |
| 1488 | Id=systemd-logind.service | |
| 1489 | Description=User Login Management | |
| 1490 | LoadState=loaded | |
| 1491 | ActiveState=active | |
| 1492 | SubState=running | |
| 1493 | FragmentPath=/usr/lib/systemd/system/systemd-logind.service | |
| 1494 | UnitFileState=static | |
| 1495 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:09 EDT | |
| 1496 | ||
| 1497 | MainPID=0 | |
| 1498 | User= | |
| 1499 | Id=systemd-machine-id-commit.service | |
| 1500 | Description=Commit a transient machine-id on disk | |
| 1501 | LoadState=loaded | |
| 1502 | ActiveState=inactive | |
| 1503 | SubState=dead | |
| 1504 | FragmentPath=/usr/lib/systemd/system/systemd-machine-id-commit.service | |
| 1505 | UnitFileState=static | |
| 1506 | ActiveEnterTimestamp= | |
| 1507 | ||
| 1508 | MainPID=0 | |
| 1509 | User= | |
| 1510 | Id=systemd-modules-load.service | |
| 1511 | Description=Load Kernel Modules | |
| 1512 | LoadState=loaded | |
| 1513 | ActiveState=active | |
| 1514 | SubState=exited | |
| 1515 | FragmentPath=/usr/lib/systemd/system/systemd-modules-load.service | |
| 1516 | UnitFileState=static | |
| 1517 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:48 EDT | |
| 1518 | ||
| 1519 | MainPID=0 | |
| 1520 | User=systemd-network | |
| 1521 | Id=systemd-networkd.service | |
| 1522 | Description=Network Configuration | |
| 1523 | LoadState=loaded | |
| 1524 | ActiveState=inactive | |
| 1525 | SubState=dead | |
| 1526 | FragmentPath=/usr/lib/systemd/system/systemd-networkd.service | |
| 1527 | UnitFileState=disabled | |
| 1528 | ActiveEnterTimestamp= | |
| 1529 | ||
| 1530 | MainPID=0 | |
| 1531 | User= | |
| 1532 | Id=systemd-oomd.service | |
| 1533 | Description=systemd-oomd.service | |
| 1534 | LoadState=not-found | |
| 1535 | ActiveState=inactive | |
| 1536 | SubState=dead | |
| 1537 | FragmentPath= | |
| 1538 | UnitFileState= | |
| 1539 | ActiveEnterTimestamp= | |
| 1540 | ||
| 1541 | MainPID=0 | |
| 1542 | User= | |
| 1543 | Id=systemd-pcrmachine.service | |
| 1544 | Description=TPM2 PCR Machine ID Measurement | |
| 1545 | LoadState=loaded | |
| 1546 | ActiveState=inactive | |
| 1547 | SubState=dead | |
| 1548 | FragmentPath=/usr/lib/systemd/system/systemd-pcrmachine.service | |
| 1549 | UnitFileState=static | |
| 1550 | ActiveEnterTimestamp= | |
| 1551 | ||
| 1552 | MainPID=0 | |
| 1553 | User= | |
| 1554 | Id=systemd-pcrphase-initrd.service | |
| 1555 | Description=TPM2 PCR Barrier (initrd) | |
| 1556 | LoadState=loaded | |
| 1557 | ActiveState=inactive | |
| 1558 | SubState=dead | |
| 1559 | FragmentPath=/usr/lib/systemd/system/systemd-pcrphase-initrd.service | |
| 1560 | UnitFileState=static | |
| 1561 | ActiveEnterTimestamp= | |
| 1562 | ||
| 1563 | MainPID=0 | |
| 1564 | User= | |
| 1565 | Id=systemd-pcrphase-sysinit.service | |
| 1566 | Description=TPM2 PCR Barrier (Initialization) | |
| 1567 | LoadState=loaded | |
| 1568 | ActiveState=inactive | |
| 1569 | SubState=dead | |
| 1570 | FragmentPath=/usr/lib/systemd/system/systemd-pcrphase-sysinit.service | |
| 1571 | UnitFileState=static | |
| 1572 | ActiveEnterTimestamp= | |
| 1573 | ||
| 1574 | MainPID=0 | |
| 1575 | User= | |
| 1576 | Id=systemd-pcrphase.service | |
| 1577 | Description=TPM2 PCR Barrier (User) | |
| 1578 | LoadState=loaded | |
| 1579 | ActiveState=inactive | |
| 1580 | SubState=dead | |
| 1581 | FragmentPath=/usr/lib/systemd/system/systemd-pcrphase.service | |
| 1582 | UnitFileState=static | |
| 1583 | ActiveEnterTimestamp= | |
| 1584 | ||
| 1585 | MainPID=0 | |
| 1586 | User= | |
| 1587 | Id=systemd-poweroff.service | |
| 1588 | Description=System Power Off | |
| 1589 | LoadState=loaded | |
| 1590 | ActiveState=inactive | |
| 1591 | SubState=dead | |
| 1592 | FragmentPath=/usr/lib/systemd/system/systemd-poweroff.service | |
| 1593 | UnitFileState=static | |
| 1594 | ActiveEnterTimestamp= | |
| 1595 | ||
| 1596 | MainPID=0 | |
| 1597 | User= | |
| 1598 | Id=systemd-pstore.service | |
| 1599 | Description=Platform Persistent Storage Archival | |
| 1600 | LoadState=loaded | |
| 1601 | ActiveState=inactive | |
| 1602 | SubState=dead | |
| 1603 | FragmentPath=/usr/lib/systemd/system/systemd-pstore.service | |
| 1604 | UnitFileState=enabled | |
| 1605 | ActiveEnterTimestamp= | |
| 1606 | ||
| 1607 | MainPID=0 | |
| 1608 | User= | |
| 1609 | Id=systemd-quotacheck.service | |
| 1610 | Description=File System Quota Check | |
| 1611 | LoadState=loaded | |
| 1612 | ActiveState=inactive | |
| 1613 | SubState=dead | |
| 1614 | FragmentPath=/usr/lib/systemd/system/systemd-quotacheck.service | |
| 1615 | UnitFileState=static | |
| 1616 | ActiveEnterTimestamp= | |
| 1617 | ||
| 1618 | MainPID=0 | |
| 1619 | User= | |
| 1620 | Id=systemd-random-seed.service | |
| 1621 | Description=Load/Save OS Random Seed | |
| 1622 | LoadState=loaded | |
| 1623 | ActiveState=active | |
| 1624 | SubState=exited | |
| 1625 | FragmentPath=/usr/lib/systemd/system/systemd-random-seed.service | |
| 1626 | UnitFileState=static | |
| 1627 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:48 EDT | |
| 1628 | ||
| 1629 | MainPID=0 | |
| 1630 | User= | |
| 1631 | Id=systemd-reboot.service | |
| 1632 | Description=System Reboot | |
| 1633 | LoadState=loaded | |
| 1634 | ActiveState=inactive | |
| 1635 | SubState=dead | |
| 1636 | FragmentPath=/usr/lib/systemd/system/systemd-reboot.service | |
| 1637 | UnitFileState=static | |
| 1638 | ActiveEnterTimestamp= | |
| 1639 | ||
| 1640 | MainPID=0 | |
| 1641 | User= | |
| 1642 | Id=systemd-remount-fs.service | |
| 1643 | Description=Remount Root and Kernel File Systems | |
| 1644 | LoadState=loaded | |
| 1645 | ActiveState=active | |
| 1646 | SubState=exited | |
| 1647 | FragmentPath=/usr/lib/systemd/system/systemd-remount-fs.service | |
| 1648 | UnitFileState=enabled-runtime | |
| 1649 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:47 EDT | |
| 1650 | ||
| 1651 | MainPID=0 | |
| 1652 | User= | |
| 1653 | Id=systemd-repart.service | |
| 1654 | Description=Repartition Root Disk | |
| 1655 | LoadState=loaded | |
| 1656 | ActiveState=inactive | |
| 1657 | SubState=dead | |
| 1658 | FragmentPath=/usr/lib/systemd/system/systemd-repart.service | |
| 1659 | UnitFileState=static | |
| 1660 | ActiveEnterTimestamp= | |
| 1661 | ||
| 1662 | MainPID=762 | |
| 1663 | User=systemd-resolve | |
| 1664 | Id=systemd-resolved.service | |
| 1665 | Description=Network Name Resolution | |
| 1666 | LoadState=loaded | |
| 1667 | ActiveState=active | |
| 1668 | SubState=running | |
| 1669 | FragmentPath=/usr/lib/systemd/system/systemd-resolved.service | |
| 1670 | UnitFileState=enabled | |
| 1671 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:07 EDT | |
| 1672 | ||
| 1673 | MainPID=0 | |
| 1674 | User= | |
| 1675 | Id=systemd-rfkill.service | |
| 1676 | Description=Load/Save RF Kill Switch Status | |
| 1677 | LoadState=loaded | |
| 1678 | ActiveState=inactive | |
| 1679 | SubState=dead | |
| 1680 | FragmentPath=/usr/lib/systemd/system/systemd-rfkill.service | |
| 1681 | UnitFileState=static | |
| 1682 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:04 EDT | |
| 1683 | ||
| 1684 | MainPID=0 | |
| 1685 | User= | |
| 1686 | Id=systemd-soft-reboot.service | |
| 1687 | Description=Reboot System Userspace | |
| 1688 | LoadState=loaded | |
| 1689 | ActiveState=inactive | |
| 1690 | SubState=dead | |
| 1691 | FragmentPath=/usr/lib/systemd/system/systemd-soft-reboot.service | |
| 1692 | UnitFileState=static | |
| 1693 | ActiveEnterTimestamp= | |
| 1694 | ||
| 1695 | MainPID=0 | |
| 1696 | User= | |
| 1697 | Id=systemd-suspend-then-hibernate.service | |
| 1698 | Description=System Suspend then Hibernate | |
| 1699 | LoadState=loaded | |
| 1700 | ActiveState=inactive | |
| 1701 | SubState=dead | |
| 1702 | FragmentPath=/usr/lib/systemd/system/systemd-suspend-then-hibernate.service | |
| 1703 | UnitFileState=static | |
| 1704 | ActiveEnterTimestamp= | |
| 1705 | ||
| 1706 | MainPID=0 | |
| 1707 | User= | |
| 1708 | Id=systemd-suspend.service | |
| 1709 | Description=System Suspend | |
| 1710 | LoadState=loaded | |
| 1711 | ActiveState=inactive | |
| 1712 | SubState=dead | |
| 1713 | FragmentPath=/usr/lib/systemd/system/systemd-suspend.service | |
| 1714 | UnitFileState=static | |
| 1715 | ActiveEnterTimestamp= | |
| 1716 | ||
| 1717 | MainPID=0 | |
| 1718 | User= | |
| 1719 | Id=systemd-sysctl.service | |
| 1720 | Description=Apply Kernel Variables | |
| 1721 | LoadState=loaded | |
| 1722 | ActiveState=active | |
| 1723 | SubState=exited | |
| 1724 | FragmentPath=/usr/lib/systemd/system/systemd-sysctl.service | |
| 1725 | UnitFileState=static | |
| 1726 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:51 EDT | |
| 1727 | ||
| 1728 | MainPID=0 | |
| 1729 | User= | |
| 1730 | Id=systemd-sysext.service | |
| 1731 | Description=Merge System Extension Images into /usr/ and /opt/ | |
| 1732 | LoadState=loaded | |
| 1733 | ActiveState=inactive | |
| 1734 | SubState=dead | |
| 1735 | FragmentPath=/usr/lib/systemd/system/systemd-sysext.service | |
| 1736 | UnitFileState=disabled | |
| 1737 | ActiveEnterTimestamp= | |
| 1738 | ||
| 1739 | MainPID=0 | |
| 1740 | User= | |
| 1741 | Id=systemd-sysusers.service | |
| 1742 | Description=Create System Users | |
| 1743 | LoadState=loaded | |
| 1744 | ActiveState=inactive | |
| 1745 | SubState=dead | |
| 1746 | FragmentPath=/usr/lib/systemd/system/systemd-sysusers.service | |
| 1747 | UnitFileState=static | |
| 1748 | ActiveEnterTimestamp= | |
| 1749 | ||
| 1750 | MainPID=763 | |
| 1751 | User=systemd-timesync | |
| 1752 | Id=systemd-timesyncd.service | |
| 1753 | Description=Network Time Synchronization | |
| 1754 | LoadState=loaded | |
| 1755 | ActiveState=active | |
| 1756 | SubState=running | |
| 1757 | FragmentPath=/usr/lib/systemd/system/systemd-timesyncd.service | |
| 1758 | UnitFileState=enabled | |
| 1759 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:07 EDT | |
| 1760 | ||
| 1761 | MainPID=0 | |
| 1762 | User= | |
| 1763 | Id=systemd-tmpfiles-clean.service | |
| 1764 | Description=Cleanup of Temporary Directories | |
| 1765 | LoadState=loaded | |
| 1766 | ActiveState=inactive | |
| 1767 | SubState=dead | |
| 1768 | FragmentPath=/usr/lib/systemd/system/systemd-tmpfiles-clean.service | |
| 1769 | UnitFileState=static | |
| 1770 | ActiveEnterTimestamp= | |
| 1771 | ||
| 1772 | MainPID=0 | |
| 1773 | User= | |
| 1774 | Id=systemd-tmpfiles-setup-dev-early.service | |
| 1775 | Description=Create Static Device Nodes in /dev gracefully | |
| 1776 | LoadState=loaded | |
| 1777 | ActiveState=active | |
| 1778 | SubState=exited | |
| 1779 | FragmentPath=/usr/lib/systemd/system/systemd-tmpfiles-setup-dev-early.service | |
| 1780 | UnitFileState=static | |
| 1781 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:50 EDT | |
| 1782 | ||
| 1783 | MainPID=0 | |
| 1784 | User= | |
| 1785 | Id=systemd-tmpfiles-setup-dev.service | |
| 1786 | Description=Create Static Device Nodes in /dev | |
| 1787 | LoadState=loaded | |
| 1788 | ActiveState=active | |
| 1789 | SubState=exited | |
| 1790 | FragmentPath=/usr/lib/systemd/system/systemd-tmpfiles-setup-dev.service | |
| 1791 | UnitFileState=static | |
| 1792 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:50 EDT | |
| 1793 | ||
| 1794 | MainPID=0 | |
| 1795 | User= | |
| 1796 | Id=systemd-tmpfiles-setup.service | |
| 1797 | Description=Create Volatile Files and Directories | |
| 1798 | LoadState=loaded | |
| 1799 | ActiveState=active | |
| 1800 | SubState=exited | |
| 1801 | FragmentPath=/usr/lib/systemd/system/systemd-tmpfiles-setup.service | |
| 1802 | UnitFileState=static | |
| 1803 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:07 EDT | |
| 1804 | ||
| 1805 | MainPID=0 | |
| 1806 | User= | |
| 1807 | Id=systemd-tpm2-setup-early.service | |
| 1808 | Description=TPM2 SRK Setup (Early) | |
| 1809 | LoadState=loaded | |
| 1810 | ActiveState=inactive | |
| 1811 | SubState=dead | |
| 1812 | FragmentPath=/usr/lib/systemd/system/systemd-tpm2-setup-early.service | |
| 1813 | UnitFileState=static | |
| 1814 | ActiveEnterTimestamp= | |
| 1815 | ||
| 1816 | MainPID=0 | |
| 1817 | User= | |
| 1818 | Id=systemd-tpm2-setup.service | |
| 1819 | Description=TPM2 SRK Setup | |
| 1820 | LoadState=loaded | |
| 1821 | ActiveState=inactive | |
| 1822 | SubState=dead | |
| 1823 | FragmentPath=/usr/lib/systemd/system/systemd-tpm2-setup.service | |
| 1824 | UnitFileState=static | |
| 1825 | ActiveEnterTimestamp= | |
| 1826 | ||
| 1827 | MainPID=0 | |
| 1828 | User= | |
| 1829 | Id=systemd-udev-settle.service | |
| 1830 | Description=Wait for udev To Complete Device Initialization | |
| 1831 | LoadState=loaded | |
| 1832 | ActiveState=inactive | |
| 1833 | SubState=dead | |
| 1834 | FragmentPath=/usr/lib/systemd/system/systemd-udev-settle.service | |
| 1835 | UnitFileState=static | |
| 1836 | ActiveEnterTimestamp= | |
| 1837 | ||
| 1838 | MainPID=0 | |
| 1839 | User= | |
| 1840 | Id=systemd-udev-trigger.service | |
| 1841 | Description=Coldplug All udev Devices | |
| 1842 | LoadState=loaded | |
| 1843 | ActiveState=active | |
| 1844 | SubState=exited | |
| 1845 | FragmentPath=/usr/lib/systemd/system/systemd-udev-trigger.service | |
| 1846 | UnitFileState=static | |
| 1847 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:47 EDT | |
| 1848 | ||
| 1849 | MainPID=410 | |
| 1850 | User= | |
| 1851 | Id=systemd-udevd.service | |
| 1852 | Description=Rule-based Manager for Device Events and Files | |
| 1853 | LoadState=loaded | |
| 1854 | ActiveState=active | |
| 1855 | SubState=running | |
| 1856 | FragmentPath=/usr/lib/systemd/system/systemd-udevd.service | |
| 1857 | UnitFileState=static | |
| 1858 | ActiveEnterTimestamp=Sat 2026-08-08 20:24:55 EDT | |
| 1859 | ||
| 1860 | MainPID=0 | |
| 1861 | User= | |
| 1862 | Id=systemd-update-done.service | |
| 1863 | Description=Update is Completed | |
| 1864 | LoadState=loaded | |
| 1865 | ActiveState=inactive | |
| 1866 | SubState=dead | |
| 1867 | FragmentPath=/usr/lib/systemd/system/systemd-update-done.service | |
| 1868 | UnitFileState=static | |
| 1869 | ActiveEnterTimestamp= | |
| 1870 | ||
| 1871 | MainPID=0 | |
| 1872 | User= | |
| 1873 | Id=systemd-update-utmp-runlevel.service | |
| 1874 | Description=Record Runlevel Change in UTMP | |
| 1875 | LoadState=loaded | |
| 1876 | ActiveState=inactive | |
| 1877 | SubState=dead | |
| 1878 | FragmentPath=/usr/lib/systemd/system/systemd-update-utmp-runlevel.service | |
| 1879 | UnitFileState=static | |
| 1880 | ActiveEnterTimestamp= | |
| 1881 | ||
| 1882 | MainPID=0 | |
| 1883 | User= | |
| 1884 | Id=systemd-update-utmp.service | |
| 1885 | Description=Record System Boot/Shutdown in UTMP | |
| 1886 | LoadState=loaded | |
| 1887 | ActiveState=active | |
| 1888 | SubState=exited | |
| 1889 | FragmentPath=/usr/lib/systemd/system/systemd-update-utmp.service | |
| 1890 | UnitFileState=static | |
| 1891 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:07 EDT | |
| 1892 | ||
| 1893 | MainPID=0 | |
| 1894 | User= | |
| 1895 | Id=systemd-user-sessions.service | |
| 1896 | Description=Permit User Sessions | |
| 1897 | LoadState=loaded | |
| 1898 | ActiveState=active | |
| 1899 | SubState=exited | |
| 1900 | FragmentPath=/usr/lib/systemd/system/systemd-user-sessions.service | |
| 1901 | UnitFileState=static | |
| 1902 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:24 EDT | |
| 1903 | ||
| 1904 | MainPID=0 | |
| 1905 | User= | |
| 1906 | Id=systemd-vconsole-setup.service | |
| 1907 | Description=systemd-vconsole-setup.service | |
| 1908 | LoadState=not-found | |
| 1909 | ActiveState=inactive | |
| 1910 | SubState=dead | |
| 1911 | FragmentPath= | |
| 1912 | UnitFileState= | |
| 1913 | ActiveEnterTimestamp= | |
| 1914 | ||
| 1915 | MainPID=793 | |
| 1916 | User= | |
| 1917 | Id=thermald.service | |
| 1918 | Description=Thermal Daemon Service | |
| 1919 | LoadState=loaded | |
| 1920 | ActiveState=active | |
| 1921 | SubState=running | |
| 1922 | FragmentPath=/usr/lib/systemd/system/thermald.service | |
| 1923 | UnitFileState=enabled | |
| 1924 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:12 EDT | |
| 1925 | ||
| 1926 | MainPID=0 | |
| 1927 | User= | |
| 1928 | Id=tlp.service | |
| 1929 | Description=tlp.service | |
| 1930 | LoadState=not-found | |
| 1931 | ActiveState=inactive | |
| 1932 | SubState=dead | |
| 1933 | FragmentPath= | |
| 1934 | UnitFileState= | |
| 1935 | ActiveEnterTimestamp= | |
| 1936 | ||
| 1937 | MainPID=0 | |
| 1938 | User= | |
| 1939 | Id=tpm-udev.service | |
| 1940 | Description=Handle dynamically added tpm devices | |
| 1941 | LoadState=loaded | |
| 1942 | ActiveState=inactive | |
| 1943 | SubState=dead | |
| 1944 | FragmentPath=/usr/lib/systemd/system/tpm-udev.service | |
| 1945 | UnitFileState=static | |
| 1946 | ActiveEnterTimestamp= | |
| 1947 | ||
| 1948 | MainPID=0 | |
| 1949 | User= | |
| 1950 | Id=tuned.service | |
| 1951 | Description=tuned.service | |
| 1952 | LoadState=not-found | |
| 1953 | ActiveState=inactive | |
| 1954 | SubState=dead | |
| 1955 | FragmentPath= | |
| 1956 | UnitFileState= | |
| 1957 | ActiveEnterTimestamp= | |
| 1958 | ||
| 1959 | MainPID=0 | |
| 1960 | User= | |
| 1961 | Id=ubuntu-system-adjustments.service | |
| 1962 | Description=Ubuntu system adjustments | |
| 1963 | LoadState=loaded | |
| 1964 | ActiveState=active | |
| 1965 | SubState=exited | |
| 1966 | FragmentPath=/usr/lib/systemd/system/ubuntu-system-adjustments.service | |
| 1967 | UnitFileState=enabled | |
| 1968 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:13 EDT | |
| 1969 | ||
| 1970 | MainPID=11797 | |
| 1971 | User= | |
| 1972 | Id=udisks2.service | |
| 1973 | Description=Disk Manager | |
| 1974 | LoadState=loaded | |
| 1975 | ActiveState=active | |
| 1976 | SubState=running | |
| 1977 | FragmentPath=/usr/lib/systemd/system/udisks2.service | |
| 1978 | UnitFileState=enabled | |
| 1979 | ActiveEnterTimestamp=Sat 2026-08-08 21:05:35 EDT | |
| 1980 | ||
| 1981 | MainPID=0 | |
| 1982 | User= | |
| 1983 | Id=ufw.service | |
| 1984 | Description=Uncomplicated firewall | |
| 1985 | LoadState=loaded | |
| 1986 | ActiveState=active | |
| 1987 | SubState=exited | |
| 1988 | FragmentPath=/usr/lib/systemd/system/ufw.service | |
| 1989 | UnitFileState=enabled | |
| 1990 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:00 EDT | |
| 1991 | ||
| 1992 | MainPID=11791 | |
| 1993 | User= | |
| 1994 | Id=upower.service | |
| 1995 | Description=Daemon for power management | |
| 1996 | LoadState=loaded | |
| 1997 | ActiveState=active | |
| 1998 | SubState=running | |
| 1999 | FragmentPath=/usr/lib/systemd/system/upower.service | |
| 2000 | UnitFileState=disabled | |
| 2001 | ActiveEnterTimestamp=Sat 2026-08-08 21:05:34 EDT | |
| 2002 | ||
| 2003 | MainPID=0 | |
| 2004 | User= | |
| 2005 | Id=user-runtime-dir@1000.service | |
| 2006 | Description=User Runtime Directory /run/user/1000 | |
| 2007 | LoadState=loaded | |
| 2008 | ActiveState=active | |
| 2009 | SubState=exited | |
| 2010 | FragmentPath=/usr/lib/systemd/system/user-runtime-dir@.service | |
| 2011 | UnitFileState=static | |
| 2012 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:54 EDT | |
| 2013 | ||
| 2014 | MainPID=0 | |
| 2015 | User= | |
| 2016 | Id=user-runtime-dir@1001.service | |
| 2017 | Description=User Runtime Directory /run/user/1001 | |
| 2018 | LoadState=loaded | |
| 2019 | ActiveState=active | |
| 2020 | SubState=exited | |
| 2021 | FragmentPath=/usr/lib/systemd/system/user-runtime-dir@.service | |
| 2022 | UnitFileState=static | |
| 2023 | ActiveEnterTimestamp=Mon 2026-10-19 12:56:13 EDT | |
| 2024 | ||
| 2025 | MainPID=1172 | |
| 2026 | User=1000 | |
| 2027 | Id=user@1000.service | |
| 2028 | Description=User Manager for UID 1000 | |
| 2029 | LoadState=loaded | |
| 2030 | ActiveState=active | |
| 2031 | SubState=running | |
| 2032 | FragmentPath=/usr/lib/systemd/system/user@.service | |
| 2033 | UnitFileState=static | |
| 2034 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:09 EDT | |
| 2035 | ||
| 2036 | MainPID=3177644 | |
| 2037 | User=1001 | |
| 2038 | Id=user@1001.service | |
| 2039 | Description=User Manager for UID 1001 | |
| 2040 | LoadState=loaded | |
| 2041 | ActiveState=active | |
| 2042 | SubState=running | |
| 2043 | FragmentPath=/usr/lib/systemd/system/user@.service | |
| 2044 | UnitFileState=static | |
| 2045 | ActiveEnterTimestamp=Mon 2026-10-19 12:56:14 EDT | |
| 2046 | ||
| 2047 | MainPID=0 | |
| 2048 | User=uuidd | |
| 2049 | Id=uuidd.service | |
| 2050 | Description=Daemon for generating UUIDs | |
| 2051 | LoadState=loaded | |
| 2052 | ActiveState=inactive | |
| 2053 | SubState=dead | |
| 2054 | FragmentPath=/usr/lib/systemd/system/uuidd.service | |
| 2055 | UnitFileState=indirect | |
| 2056 | ActiveEnterTimestamp= | |
| 2057 | ||
| 2058 | MainPID=0 | |
| 2059 | User= | |
| 2060 | Id=wicd.service | |
| 2061 | Description=wicd.service | |
| 2062 | LoadState=not-found | |
| 2063 | ActiveState=inactive | |
| 2064 | SubState=dead | |
| 2065 | FragmentPath= | |
| 2066 | UnitFileState= | |
| 2067 | ActiveEnterTimestamp= | |
| 2068 | ||
| 2069 | MainPID=888 | |
| 2070 | User= | |
| 2071 | Id=wpa_supplicant.service | |
| 2072 | Description=WPA supplicant | |
| 2073 | LoadState=loaded | |
| 2074 | ActiveState=active | |
| 2075 | SubState=running | |
| 2076 | FragmentPath=/usr/lib/systemd/system/wpa_supplicant.service | |
| 2077 | UnitFileState=enabled | |
| 2078 | ActiveEnterTimestamp=Sat 2026-08-08 20:25:12 EDT |
| … | … | @@ -0,0 +1,274 @@ |
| 1 | MainPID=719556 | |
| 2 | User= | |
| 3 | Id=at-spi-dbus-bus.service | |
| 4 | Description=Accessibility services bus | |
| 5 | LoadState=loaded | |
| 6 | ActiveState=active | |
| 7 | SubState=running | |
| 8 | FragmentPath=/usr/lib/systemd/user/at-spi-dbus-bus.service | |
| 9 | UnitFileState=static | |
| 10 | ActiveEnterTimestamp=Mon 2026-08-10 12:30:12 EDT | |
| 11 | ||
| 12 | MainPID=1241 | |
| 13 | User= | |
| 14 | Id=dbus.service | |
| 15 | Description=D-Bus User Message Bus | |
| 16 | LoadState=loaded | |
| 17 | ActiveState=active | |
| 18 | SubState=running | |
| 19 | FragmentPath=/usr/lib/systemd/user/dbus.service | |
| 20 | UnitFileState=static | |
| 21 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:19 EDT | |
| 22 | ||
| 23 | MainPID=0 | |
| 24 | User= | |
| 25 | Id=dirmngr.service | |
| 26 | Description=GnuPG network certificate management daemon | |
| 27 | LoadState=loaded | |
| 28 | ActiveState=inactive | |
| 29 | SubState=dead | |
| 30 | FragmentPath=/usr/lib/systemd/user/dirmngr.service | |
| 31 | UnitFileState=static | |
| 32 | ActiveEnterTimestamp= | |
| 33 | ||
| 34 | MainPID=1230 | |
| 35 | User= | |
| 36 | Id=filter-chain.service | |
| 37 | Description=PipeWire filter chain daemon | |
| 38 | LoadState=loaded | |
| 39 | ActiveState=active | |
| 40 | SubState=running | |
| 41 | FragmentPath=/usr/lib/systemd/user/filter-chain.service | |
| 42 | UnitFileState=enabled | |
| 43 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:09 EDT | |
| 44 | ||
| 45 | MainPID=0 | |
| 46 | User= | |
| 47 | Id=gcr-ssh-agent.service | |
| 48 | Description=GCR ssh-agent wrapper | |
| 49 | LoadState=loaded | |
| 50 | ActiveState=inactive | |
| 51 | SubState=dead | |
| 52 | FragmentPath=/usr/lib/systemd/user/gcr-ssh-agent.service | |
| 53 | UnitFileState=enabled | |
| 54 | ActiveEnterTimestamp= | |
| 55 | ||
| 56 | MainPID=0 | |
| 57 | User= | |
| 58 | Id=gnome-keyring-daemon.service | |
| 59 | Description=GNOME Keyring daemon | |
| 60 | LoadState=loaded | |
| 61 | ActiveState=inactive | |
| 62 | SubState=dead | |
| 63 | FragmentPath=/usr/lib/systemd/user/gnome-keyring-daemon.service | |
| 64 | UnitFileState=enabled | |
| 65 | ActiveEnterTimestamp= | |
| 66 | ||
| 67 | MainPID=0 | |
| 68 | User= | |
| 69 | Id=gpg-agent.service | |
| 70 | Description=GnuPG cryptographic agent and passphrase cache | |
| 71 | LoadState=loaded | |
| 72 | ActiveState=inactive | |
| 73 | SubState=dead | |
| 74 | FragmentPath=/usr/lib/systemd/user/gpg-agent.service | |
| 75 | UnitFileState=static | |
| 76 | ActiveEnterTimestamp= | |
| 77 | ||
| 78 | MainPID=719494 | |
| 79 | User= | |
| 80 | Id=gvfs-daemon.service | |
| 81 | Description=Virtual filesystem service | |
| 82 | LoadState=loaded | |
| 83 | ActiveState=active | |
| 84 | SubState=running | |
| 85 | FragmentPath=/usr/lib/systemd/user/gvfs-daemon.service | |
| 86 | UnitFileState=static | |
| 87 | ActiveEnterTimestamp=Mon 2026-08-10 12:30:03 EDT | |
| 88 | ||
| 89 | MainPID=0 | |
| 90 | User= | |
| 91 | Id=keyboxd.service | |
| 92 | Description=GnuPG public key management service | |
| 93 | LoadState=loaded | |
| 94 | ActiveState=inactive | |
| 95 | SubState=dead | |
| 96 | FragmentPath=/usr/lib/systemd/user/keyboxd.service | |
| 97 | UnitFileState=static | |
| 98 | ActiveEnterTimestamp= | |
| 99 | ||
| 100 | MainPID=1227 | |
| 101 | User= | |
| 102 | Id=kodi-repo.service | |
| 103 | Description=Kodi addon update repo (patched Jacktook fork) | |
| 104 | LoadState=loaded | |
| 105 | ActiveState=active | |
| 106 | SubState=running | |
| 107 | FragmentPath=/home/fleeky/.config/systemd/user/kodi-repo.service | |
| 108 | UnitFileState=enabled | |
| 109 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:09 EDT | |
| 110 | ||
| 111 | MainPID=0 | |
| 112 | User= | |
| 113 | Id=launchpadlib-cache-clean.service | |
| 114 | Description=Clean up old files in the Launchpadlib cache | |
| 115 | LoadState=loaded | |
| 116 | ActiveState=inactive | |
| 117 | SubState=dead | |
| 118 | FragmentPath=/usr/lib/systemd/user/launchpadlib-cache-clean.service | |
| 119 | UnitFileState=static | |
| 120 | ActiveEnterTimestamp= | |
| 121 | ||
| 122 | MainPID=0 | |
| 123 | User= | |
| 124 | Id=pipewire-media-session.service | |
| 125 | Description=pipewire-media-session.service | |
| 126 | LoadState=not-found | |
| 127 | ActiveState=inactive | |
| 128 | SubState=dead | |
| 129 | FragmentPath= | |
| 130 | UnitFileState= | |
| 131 | ActiveEnterTimestamp= | |
| 132 | ||
| 133 | MainPID=1234 | |
| 134 | User= | |
| 135 | Id=pipewire-pulse.service | |
| 136 | Description=PipeWire PulseAudio | |
| 137 | LoadState=loaded | |
| 138 | ActiveState=active | |
| 139 | SubState=running | |
| 140 | FragmentPath=/usr/lib/systemd/user/pipewire-pulse.service | |
| 141 | UnitFileState=enabled | |
| 142 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:09 EDT | |
| 143 | ||
| 144 | MainPID=0 | |
| 145 | User= | |
| 146 | Id=pipewire-session-manager.service | |
| 147 | Description=pipewire-session-manager.service | |
| 148 | LoadState=not-found | |
| 149 | ActiveState=inactive | |
| 150 | SubState=dead | |
| 151 | FragmentPath= | |
| 152 | UnitFileState= | |
| 153 | ActiveEnterTimestamp= | |
| 154 | ||
| 155 | MainPID=1228 | |
| 156 | User= | |
| 157 | Id=pipewire.service | |
| 158 | Description=PipeWire Multimedia Service | |
| 159 | LoadState=loaded | |
| 160 | ActiveState=active | |
| 161 | SubState=running | |
| 162 | FragmentPath=/usr/lib/systemd/user/pipewire.service | |
| 163 | UnitFileState=enabled | |
| 164 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:09 EDT | |
| 165 | ||
| 166 | MainPID=0 | |
| 167 | User= | |
| 168 | Id=pk-debconf-helper.service | |
| 169 | Description=debconf communication service | |
| 170 | LoadState=loaded | |
| 171 | ActiveState=inactive | |
| 172 | SubState=dead | |
| 173 | FragmentPath=/usr/lib/systemd/user/pk-debconf-helper.service | |
| 174 | UnitFileState=static | |
| 175 | ActiveEnterTimestamp= | |
| 176 | ||
| 177 | MainPID=0 | |
| 178 | User= | |
| 179 | Id=pulseaudio.service | |
| 180 | Description=pulseaudio.service | |
| 181 | LoadState=not-found | |
| 182 | ActiveState=inactive | |
| 183 | SubState=dead | |
| 184 | FragmentPath= | |
| 185 | UnitFileState= | |
| 186 | ActiveEnterTimestamp= | |
| 187 | ||
| 188 | MainPID=0 | |
| 189 | User= | |
| 190 | Id=speech-dispatcher.service | |
| 191 | Description=Common interface to speech synthesizers | |
| 192 | LoadState=loaded | |
| 193 | ActiveState=inactive | |
| 194 | SubState=dead | |
| 195 | FragmentPath=/usr/lib/systemd/user/speech-dispatcher.service | |
| 196 | UnitFileState=static | |
| 197 | ActiveEnterTimestamp= | |
| 198 | ||
| 199 | MainPID=3079448 | |
| 200 | User= | |
| 201 | Id=stremio-vsembed.service | |
| 202 | Description=Stremio VsEmbed extractor addon | |
| 203 | LoadState=loaded | |
| 204 | ActiveState=active | |
| 205 | SubState=running | |
| 206 | FragmentPath=/home/fleeky/.config/systemd/user/stremio-vsembed.service | |
| 207 | UnitFileState=enabled | |
| 208 | ActiveEnterTimestamp=Sun 2026-10-18 21:51:11 EDT | |
| 209 | ||
| 210 | MainPID=0 | |
| 211 | User= | |
| 212 | Id=systemd-remount-fs.service | |
| 213 | Description=systemd-remount-fs.service | |
| 214 | LoadState=not-found | |
| 215 | ActiveState=inactive | |
| 216 | SubState=dead | |
| 217 | FragmentPath= | |
| 218 | UnitFileState= | |
| 219 | ActiveEnterTimestamp= | |
| 220 | ||
| 221 | MainPID=1233 | |
| 222 | User= | |
| 223 | Id=wireplumber.service | |
| 224 | Description=Multimedia Service Session Manager | |
| 225 | LoadState=loaded | |
| 226 | ActiveState=active | |
| 227 | SubState=running | |
| 228 | FragmentPath=/usr/lib/systemd/user/wireplumber.service | |
| 229 | UnitFileState=enabled | |
| 230 | ActiveEnterTimestamp=Sat 2026-08-08 20:26:09 EDT | |
| 231 | ||
| 232 | MainPID=0 | |
| 233 | User= | |
| 234 | Id=xdg-desktop-portal-gtk.service | |
| 235 | Description=Portal service (GTK/GNOME implementation) | |
| 236 | LoadState=loaded | |
| 237 | ActiveState=failed | |
| 238 | SubState=failed | |
| 239 | FragmentPath=/usr/lib/systemd/user/xdg-desktop-portal-gtk.service | |
| 240 | UnitFileState=static | |
| 241 | ActiveEnterTimestamp= | |
| 242 | ||
| 243 | MainPID=0 | |
| 244 | User= | |
| 245 | Id=xdg-desktop-portal.service | |
| 246 | Description=Portal service | |
| 247 | LoadState=loaded | |
| 248 | ActiveState=failed | |
| 249 | SubState=failed | |
| 250 | FragmentPath=/usr/lib/systemd/user/xdg-desktop-portal.service | |
| 251 | UnitFileState=static | |
| 252 | ActiveEnterTimestamp= | |
| 253 | ||
| 254 | MainPID=719662 | |
| 255 | User= | |
| 256 | Id=xdg-document-portal.service | |
| 257 | Description=flatpak document portal service | |
| 258 | LoadState=loaded | |
| 259 | ActiveState=active | |
| 260 | SubState=running | |
| 261 | FragmentPath=/usr/lib/systemd/user/xdg-document-portal.service | |
| 262 | UnitFileState=static | |
| 263 | ActiveEnterTimestamp=Mon 2026-08-10 12:30:26 EDT | |
| 264 | ||
| 265 | MainPID=719657 | |
| 266 | User= | |
| 267 | Id=xdg-permission-store.service | |
| 268 | Description=sandboxed app permission store | |
| 269 | LoadState=loaded | |
| 270 | ActiveState=active | |
| 271 | SubState=running | |
| 272 | FragmentPath=/usr/lib/systemd/user/xdg-permission-store.service | |
| 273 | UnitFileState=static | |
| 274 | ActiveEnterTimestamp=Mon 2026-08-10 12:30:25 EDT |
| … | … | @@ -0,0 +1,96 @@ |
| 1 | // Parsers against output captured on stortron (2026-10-19). | |
| 2 | import test from 'brittle' | |
| 3 | import fs from 'bare-fs' | |
| 4 | import path from 'bare-path' | |
| 5 | import { | |
| 6 | parseProcNetTcp, bindScope, parseSystemctlShow, isVendorUnit, parsePghStatus, | |
| 7 | parseHttpHead, extractTitle, parseArp, parseAvahiBrowse, parseIpAddr | |
| 8 | } from '../lib/parse.js' | |
| 9 | ||
| 10 | const FIX = path.join(path.dirname(new URL(import.meta.url).pathname), 'fixtures') | |
| 11 | const fix = (name) => fs.readFileSync(path.join(FIX, name)).toString() | |
| 12 | ||
| 13 | test('proc/net/tcp: LISTEN rows only, addresses and owners decoded', (t) => { | |
| 14 | const rows = parseProcNetTcp(fix('proc-net-tcp.txt'), 4) | |
| 15 | const jellyfin = rows.find((r) => r.port === 8096) | |
| 16 | t.is(jellyfin.addr, '0.0.0.0') | |
| 17 | t.is(jellyfin.uid, 122) | |
| 18 | t.is(rows.filter((r) => r.port === 8096).length, 1, 'established 8096 connections are not listeners') | |
| 19 | const host = rows.find((r) => r.port === 4042) | |
| 20 | t.is(host.addr, '127.0.0.1') | |
| 21 | t.is(host.uid, 1000) | |
| 22 | }) | |
| 23 | ||
| 24 | test('proc/net/tcp6: any and loopback addresses', (t) => { | |
| 25 | const rows = parseProcNetTcp(fix('proc-net-tcp6.txt'), 6) | |
| 26 | t.ok(rows.length > 0) | |
| 27 | const https = rows.find((r) => r.port === 443) | |
| 28 | t.is(https.addr, '::') | |
| 29 | t.is(bindScope(https.addr), 'all') | |
| 30 | t.ok(rows.some((r) => r.addr === '::1' && r.port === 631), 'cups on ::1') | |
| 31 | }) | |
| 32 | ||
| 33 | test('bindScope', (t) => { | |
| 34 | t.is(bindScope('0.0.0.0'), 'all') | |
| 35 | t.is(bindScope('127.0.0.53'), 'local') | |
| 36 | t.is(bindScope('::1'), 'local') | |
| 37 | t.is(bindScope('192.168.50.215'), 'addr') | |
| 38 | }) | |
| 39 | ||
| 40 | test('systemctl show: blocks become units; vendor vs hand-installed', (t) => { | |
| 41 | const units = parseSystemctlShow(fix('systemctl-show.txt')) | |
| 42 | const j = units.find((u) => u.Id === 'jellyfin.service') | |
| 43 | t.is(j.ActiveState, 'active') | |
| 44 | t.is(j.User, 'jellyfin') | |
| 45 | t.ok(isVendorUnit(j)) | |
| 46 | const user = parseSystemctlShow(fix('systemctl-user-show.txt')) | |
| 47 | const k = user.find((u) => u.Id === 'kodi-repo.service') | |
| 48 | t.is(k.ActiveState, 'active') | |
| 49 | t.absent(isVendorUnit(k), 'a unit in ~/.config/systemd is hand-installed') | |
| 50 | }) | |
| 51 | ||
| 52 | test('pgh app status table', (t) => { | |
| 53 | const apps = parsePghStatus(fix('pgh-app-status.txt')) | |
| 54 | t.is(apps.length, 18) | |
| 55 | const c = apps.find((a) => a.name === 'cthuloid-web') | |
| 56 | t.is(c.running, true) | |
| 57 | t.is(c.pid, 1945148) | |
| 58 | t.is(c.autostart, true) | |
| 59 | t.is(c.version, '0.2.1') | |
| 60 | const w = apps.find((a) => a.name === 'favela-web') | |
| 61 | t.is(w.running, false) | |
| 62 | t.is(w.autostart, false) | |
| 63 | t.is(apps.find((a) => a.name === 'favela-gateway').lastExitCode, 75) | |
| 64 | t.is(apps.find((a) => a.name === 'hyper-tps').lastExitCode, null, 'never started: no exit code') | |
| 65 | }) | |
| 66 | ||
| 67 | test('HTTP head: status, redirect, title; non-HTTP is null', (t) => { | |
| 68 | const h = parseHttpHead('HTTP/1.1 302 Found\r\nLocation: /login\r\nServer: Kestrel\r\n\r\n') | |
| 69 | t.is(h.code, 302) | |
| 70 | t.is(h.location, '/login') | |
| 71 | t.is(h.server, 'Kestrel') | |
| 72 | const p = parseHttpHead('HTTP/1.0 200 OK\r\n\r\n<html><head><title>\n repos · pear-git-v3 </title>') | |
| 73 | t.is(p.title, 'repos · pear-git-v3') | |
| 74 | t.is(parseHttpHead('SSH-2.0-OpenSSH_9.6p1\r\n'), null) | |
| 75 | t.is(extractTitle('<p>no title</p>'), null) | |
| 76 | }) | |
| 77 | ||
| 78 | test('arp: complete entries only', (t) => { | |
| 79 | const arp = parseArp(fix('proc-net-arp.txt')) | |
| 80 | t.ok(arp.length > 5) | |
| 81 | t.ok(arp.every((a) => /^[0-9a-f:]{17}$/.test(a.mac) && a.mac !== '00:00:00:00:00:00')) | |
| 82 | t.ok(arp.some((a) => a.ip === '192.168.50.228')) | |
| 83 | t.is(parseArp('IP address HW type Flags HW address Mask Device\n192.168.50.9 0x1 0x0 00:00:00:00:00:00 * enp2s0\n').length, 0) | |
| 84 | }) | |
| 85 | ||
| 86 | test('avahi browse: resolved IPv4 services', (t) => { | |
| 87 | const svcs = parseAvahiBrowse(fix('avahi-browse.txt')) | |
| 88 | t.ok(svcs.length > 0) | |
| 89 | t.ok(svcs.every((s) => /^\d+\.\d+\.\d+\.\d+$/.test(s.ip) && Number.isInteger(s.port))) | |
| 90 | t.ok(svcs.some((s) => s.type === '_spotify-connect._tcp' && s.ip === '192.168.50.111')) | |
| 91 | }) | |
| 92 | ||
| 93 | test('ip addr: LAN and tunnel addresses', (t) => { | |
| 94 | const a = parseIpAddr(fix('ip-addr.txt')) | |
| 95 | t.alike(a.map((x) => [x.dev, x.ip, x.prefix]), [['enp2s0', '192.168.50.215', 24], ['tunnel0', '10.22.0.2', 16]]) | |
| 96 | }) |