Current section

Files

Jump to
exosql lib extractors node.ex
Raw

lib/extractors/node.ex

defmodule ExoSQL.Node do
@moduledoc """
Example extractor that gather information from the system
Currently only supports the `passwd` table.
"""
def schema(_db), do: {:ok, ["passwd", "proc"]}
def schema(_db, "passwd") do
{:ok,
%{
columns: [
"user",
"x",
"uid",
"gid",
"name",
"home",
"shell"
]
}}
end
def schema(_db, "proc") do
{:ok,
%{
columns: [
"pid",
"cmd",
"args"
]
}}
end
def execute(_db, "passwd", _quals, _columns) do
csv_data = File.stream!("/etc/passwd") |> CSV.decode(separator: ?:)
rows =
for l <- csv_data do
{:ok, l} = l
l
end
{:ok,
%{
columns: [
"user",
"x",
"uid",
"gid",
"name",
"home",
"shell"
],
rows: rows
}}
end
def execute(_config, "proc", _quals, columns) do
known_columns = ["pid", "cmd", "args"]
for c <- columns do
if not (c in known_columns) do
raise MatchError, {:unknown_column, c}
end
end
{:ok, proc} = File.ls("/proc/")
# Keep only numeric procs
proc =
Enum.flat_map(proc, fn n ->
case Integer.parse(n) do
{n, ""} -> [n]
_ -> []
end
end)
rows =
Enum.map(proc, &{File.open("/proc/#{&1}/cmdline"), &1})
|> Enum.flat_map(fn
{{:ok, fd}, pid} ->
case IO.read(fd, 1024) do
:eof ->
[]
data ->
[cmd | args] = String.split(data, "\0")
[[pid, cmd, args]]
end
_ ->
[]
end)
{:ok,
%{
columns: known_columns,
rows: rows
}}
end
end