blob: d2ecce30392ebac7c09f0fb8270b09065d279b1c [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/loop.h>
#include <lib/async/dispatcher.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/syslog/cpp/log_settings.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/result.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <fbl/ref_ptr.h>
#include "src/developer/vsock-sshd-host/data_dir.h"
#include "src/developer/vsock-sshd-host/service.h"
#include "src/storage/lib/vfs/cpp/pseudo_dir.h"
#include "src/storage/lib/vfs/cpp/vfs_types.h"
#include "src/storage/lib/vfs/cpp/vnode.h"
namespace {
const uint16_t kPort = 22;
class DevNullVnode : public fs::Vnode {
public:
explicit DevNullVnode() = default;
zx_status_t Read(void* data, size_t len, size_t off, size_t* out_actual) override {
*out_actual = 0;
return ZX_OK;
}
zx_status_t Write(const void* data, size_t len, size_t off, size_t* out_actual) override {
*out_actual = len;
return ZX_OK;
}
zx_status_t Truncate(size_t len) override { return ZX_OK; }
zx::result<fs::VnodeAttributes> GetAttributes() const override {
return zx::ok(fs::VnodeAttributes{
.mode = V_TYPE_CDEV | V_IRUSR | V_IWUSR,
});
}
fuchsia_io::NodeProtocolKinds GetProtocols() const override {
return fuchsia_io::NodeProtocolKinds::kFile;
}
};
} // namespace
int main(int argc, const char** argv) {
fuchsia_logging::SetTags({"sshd-host"});
FX_SLOG(INFO, "sshd-host starting up");
async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
zx::result result = memfs::Memfs::Create(loop.dispatcher(), "data");
if (result.is_error()) {
FX_LOGS(FATAL) << "Failed to create memfs with error " << result.status_string();
}
auto& [memfs, data_dir] = result.value();
{
auto result = BuildDataDir(loop, memfs.get(), data_dir);
if (result.is_error()) {
FX_LOGS(FATAL) << "Failed to create build data dir with error " << result.status_string();
}
}
auto root = fbl::MakeRefCounted<fs::PseudoDir>();
root->AddEntry("data", std::move(data_dir));
auto dev = fbl::MakeRefCounted<fs::PseudoDir>();
dev->AddEntry("null", fbl::MakeRefCounted<DevNullVnode>());
root->AddEntry("dev", std::move(dev));
// Serve outgoing directory
auto outgoing_request = fidl::ServerEnd<fuchsia_io::Directory>(
zx::channel((zx_take_startup_handle(PA_DIRECTORY_REQUEST))));
if (zx_status_t status = memfs->ServeDirectory(std::move(root), std::move(outgoing_request));
status != ZX_OK) {
FX_LOGS(FATAL) << "Failed to host outgoing directory " << status;
}
uint16_t port = kPort;
if (argc > 1) {
int arg = atoi(argv[1]);
if (arg <= 0) {
FX_SLOG(ERROR, "Invalid port", FX_KV("argv[1]", argv[1]));
return -1;
}
port = static_cast<uint16_t>(arg);
}
sshd_host::Service service(loop.dispatcher(), port);
if (zx_status_t status = loop.Run(); status != ZX_OK) {
FX_SLOG(FATAL, "Failed to run loop", FX_KV("status", zx_status_get_string(status)));
}
return 0;
}