bool SocketUpdate(size_t type, const AuditFields& fields, AuditFields& r) {
  if (type == AUDIT_TYPE_SOCKADDR) {
    const auto& saddr = fields.at("saddr");
    if (saddr.size() < 4 || saddr[0] == '1') {
      return false;
    }

    r["protocol"] = '0';
    r["local_port"] = '0';
    r["remote_port"] = '0';
    // Parse the struct and emit the row.
    if (!parseSockAddr(saddr, r)) {
      return false;
    }
    return true;
  }

  r["auid"] = fields.at("auid");
  r["pid"] = fields.at("pid");
  r["path"] = decodeAuditValue(fields.at("exe"));
  // TODO: This is a hex value.
  r["fd"] = fields.at("a0");
  // The open/bind success status.
  r["success"] = (fields.at("success") == "yes") ? "1" : "0";
  r["uptime"] = std::to_string(tables::getUptime());
  return true;
}
bool ProcessUpdate(size_t type, const AuditFields& fields, AuditFields& r) {
  if (type == AUDIT_SYSCALL) {
    r["pid"] = (fields.count("pid")) ? fields.at("pid") : "0";
    r["parent"] = fields.count("ppid") ? fields.at("ppid") : "0";
    r["uid"] = fields.count("uid") ? fields.at("uid") : "0";
    r["euid"] = fields.count("euid") ? fields.at("euid") : "0";
    r["gid"] = fields.count("gid") ? fields.at("gid") : "0";
    r["egid"] = fields.count("egid") ? fields.at("euid") : "0";
    r["path"] = (fields.count("exe")) ? decodeAuditValue(fields.at("exe")) : "";

    auto qd = SQL::selectAllFrom("file", "path", EQUALS, r.at("path"));
    if (qd.size() == 1) {
      r["ctime"] = qd.front().at("ctime");
      r["atime"] = qd.front().at("atime");
      r["mtime"] = qd.front().at("mtime");
      r["btime"] = "0";
    }

    // This should get overwritten during the EXECVE state.
    r["cmdline"] = (fields.count("comm")) ? fields.at("comm") : "";
    // Do not record a cmdline size. If the final state is reached and no
    // 'argc'
    // has been filled in then the EXECVE state was not used.
    r["cmdline_size"] = "";

    r["overflows"] = "";
    r["env_size"] = "0";
    r["env_count"] = "0";
    r["env"] = "";
  }

  if (type == AUDIT_EXECVE) {
    // Reset the temporary storage from the SYSCALL state.
    r["cmdline"] = "";
    for (const auto& arg : fields) {
      if (arg.first == "argc") {
        continue;
      }

      // Amalgamate all the "arg*" fields.
      if (r.at("cmdline").size() > 0) {
        r["cmdline"] += " ";
      }
      r["cmdline"] += decodeAuditValue(arg.second);
    }

    // There may be a better way to calculate actual size from audit.
    // Then an overflow could be calculated/determined based on
    // actual/expected.
    r["cmdline_size"] = std::to_string(r.at("cmdline").size());

    // Uptime is helpful for execution-based events.
    r["uptime"] = std::to_string(tables::getUptime());
  }

  if (type == AUDIT_PATH) {
    r["mode"] = (fields.count("mode")) ? fields.at("mode") : "";
    r["owner_uid"] = fields.count("ouid") ? fields.at("ouid") : "0";
    r["owner_gid"] = fields.count("ogid") ? fields.at("ogid") : "0";
  }
  return true;
}