changeset 28:4493eb3a98df

ssh: initial import
author David Demelier <markand@malikania.fr>
date Fri, 27 Apr 2018 11:50:07 +0200
parents ce74602c837f
children 23ff08a712b5
files CMakeLists.txt TODO.md dmenu-ssh/CMakeLists.txt dmenu-ssh/main.cpp
diffstat 4 files changed, 129 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Fri Apr 27 10:21:20 2018 +0200
+++ b/CMakeLists.txt	Fri Apr 27 11:50:07 2018 +0200
@@ -30,9 +30,11 @@
 add_subdirectory(libdmenutools)
 add_subdirectory(dmenu-background)
 add_subdirectory(dmenu-mpc)
+add_subdirectory(dmenu-ssh)
 
 message("")
 message("dmenutools configuration")
 message("    dmenu-background:  ${WITH_BACKGROUND_MSG}")
 message("    dmenu-mpc:         ${WITH_MPC_MSG}")
+message("    dmenu-ssh:         ${WITH_SSH_MSG}")
 message("")
--- a/TODO.md	Fri Apr 27 10:21:20 2018 +0200
+++ b/TODO.md	Fri Apr 27 11:50:07 2018 +0200
@@ -27,7 +27,6 @@
 
 | Name              | Description        | Requirements | Level  |
 |-------------------|--------------------|--------------|--------|
-| `dmenu-ssh`       | open a SSH session | none         | easy   |
 | `dmenu-nm`        | manage wifi/eth    | dbus         | hard   |
 | `dmenu-xrandr`    | manage screens     | libXrandr    | hard   |
 | `dmenu-bluetooth` | manage bluetooth   | dbus         | medium |
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmenu-ssh/CMakeLists.txt	Fri Apr 27 11:50:07 2018 +0200
@@ -0,0 +1,25 @@
+#
+# CMakeLists.txt -- CMake build system for dmenutools
+#
+# Copyright (c) 2018 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(dmenu-ssh)
+
+define_executable(
+    NAME ssh
+    SOURCES main.cpp
+)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmenu-ssh/main.cpp	Fri Apr 27 11:50:07 2018 +0200
@@ -0,0 +1,102 @@
+/*
+ * main.cpp -- open ssh session
+ *
+ * Copyright (c) 2018 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <regex>
+#include <sstream>
+#include <stdexcept>
+
+#include <unistd.h>
+
+#include <dmenu/dmenu.hpp>
+
+using namespace std::string_literals;
+
+namespace {
+
+auto path() -> std::string
+{
+    const auto home = std::getenv("HOME");
+
+    if (!home)
+        throw std::runtime_error("could not get HOME");
+
+    return std::string(home) + "/.ssh/config";
+}
+
+auto list() -> std::vector<std::string>
+{
+    std::ifstream config(path());
+
+    if (!config)
+        throw std::runtime_error(std::strerror(errno));
+
+    std::vector<std::string> lines;
+    std::regex regex("Host (\\S+)");
+
+    for (std::string line; std::getline(config, line); ) {
+        std::smatch match;
+
+        if (!std::regex_match(line, match, regex))
+            continue;
+
+        lines.push_back(match[1]);
+    }
+
+    return lines;
+}
+
+auto terminal() -> std::string
+{
+    const auto section = dmenu::config("ssh");
+    const auto terminal = section.get("terminal").get_value();
+
+    return terminal.empty() ? "xterm" : terminal;
+}
+
+auto menu() -> std::string
+{
+    return dmenu::run({ "-l 16", "-p ssh" }, list());
+}
+
+void exec(const std::string& host)
+{
+    const auto term = terminal();
+    const char* list[] = { term.c_str(), "-e", "ssh", host.c_str(), nullptr };
+
+    execvp(term.c_str(), (char**)list);
+}
+
+} // !namespace
+
+int main()
+{
+    try {
+        const auto selection = menu();
+
+        if (!selection.empty())
+            exec(selection);
+    } catch (const std::exception& ex) {
+        std::cerr << "abort: " << ex.what() << std::endl;
+        return 1;
+    }
+}