magのOSS備忘録

使ったOSSソフトウェアについて書いていきます。

Windows版GNU EmacsのTRAMPで秘密鍵を指定してssh接続する (plink使用)

動機

TRAMPを使ってリモートサーバのファイルを編集しようと思ったときに, SSHで公開鍵認証方式でログインしようとしたら, 色々大変だったのでやり方を残す.

複数のサーバに接続する場合, ユーザ名, ホスト名(もしくはIPアドレス), 秘密鍵ファイルを組み合わせた設定を用意しておき, それを使い分けるようにしたい. elispで設定を分けることもできそうだが, 今回はPuTTY側で複数の設定を保存しておくことにした.

実行環境

必要なもの

plinkを使ったSSH接続の手順

色々調べた結果, WindowsからSSHプロトコルでリモートサーバに接続するために, plinkを使用することにした.
plinkPuTTYに付属して配布されているため, PuTTYをインストールする.
PuTTYは下記のリンク先から, Kentaro Sato氏のカスタムビルド版PuTTY-ranvisを使用させてもらった.

PuTTY-ranvis - Ranvis software

PuTTY-ranvisのインストール

任意のフォルダに解凍する. その後, 解凍したフォルダへパスを通しておく.
今回は環境変数PATHにフォルダを追加し, コマンドプロンプトからplinkが実行できることを確認した.

PuTTYでのセッション登録

EmacsのTRAMPで接続先を選択するために, PuTTYで登録したセッション名を指定する.
そのため, 予めPuTTYでセッションを登録しておく.

設定しておくパラメータは下記の通りで, ここでホスト名, ユーザ名, 秘密鍵の組み合わせを保持する形になる.

  • セッション - 接続先の指定 - ホスト名 にホスト名かIPアドレスを入れる.
  • 接続 - データ - ログインの詳細 - 自動ログインのユーザ名 にユーザ名を入れる.
  • 接続 - SSH - PuTTYツール間で SSH 接続を共有する - 可能ならば SSH 接続を共有する にチェックを入れる.
  • 接続 - SSH - 認証 - 認証パラメータ - 認証のための秘密鍵ファイル にPuTTY形式の秘密鍵のパスを入力する.
  • セッション - 保存済みセッション一覧 に, 名称をつけて保存する. この名称をあとでEmacsで指定する.

なお, 公開鍵/秘密鍵はputtygen.exeで作れる. 作成方法やサーバへの登録はここでは割愛する.

PuTTYでのSSH接続

PuTTYを実行し, 上記で登録したセッションを開いておく.

Emacs上での設定

plinkEmacsから参照できるようになっている必要がある.
今回は環境変数PATHにplinkまでのパスを登録しているので, Emacs側では特に設定は不要.

もし上手く認識されないようであれば, *scratch*バッファで下記を評価し, パスが含まれてるかを確認する.

(getenv "PATH")

Emacs上での操作

Emacs上で下記のように入力し, リモートサーバのファイルが開ければ成功.

C-x C-f /plinkx:session-name:/directory/file

注意点は, plinkではなくplinkxを使用すること.
そして, ここでsession-nameと記載した部分には, PuTTYで登録したセッション名を指定する.

参考

flycheckでC/C++のプロジェクトごとの設定を行う

動機

通常, C/C++(に限ったことではないが)プロジェクトではそれぞれで定義するヘッダファイルをインクルードするため, 全体的に共通の設定を行うと余計な設定まで含んでしまうことになる. プロジェクトAでインクルードするファイルは, プロジェクトBではインクルードしないが共通の設定を使っていると, プロジェクトBでは不要な設定を適用することになる. そのため, プロジェクトごと(ディレクトリごと)に設定を行いたい.

ディレクトリごとにローカルな変数設定

Emacsには「.dir-locals.el」というファイルによって, そのディレクトリとその配下のディレクトリにのみ適用する設定を記載することが出来る.

例えば下記のようなディレクトリ構造で, projectディレクトリの直下に.dir-locals.elが配置してあると, includeやsrcディレクトリにあるファイルを開いたときにも.dir-locals.elファイルの内容が適用される.

project
├── .dir-locals.el
├── include
│   └── common.h
└── src
    ├── main.cpp
    ├── sub.cpp
    └── sub.h

flycheckの場合

flycheckでも.dir-locals.elの設定が適用される. 例えば, 下記のように設定することで, そのプロジェクト(ディレクトリ)配下のソースコードを開いたときに有効な設定を書くことが出来る.

((nil . ((flycheck-clang-language-standard . "c++11") ; このプロジェクトはC++11に対応している
         (flycheck-clang-include-path . ("."          ; インクルードパスを設定する
                                         "src"
                                         "include"
                                         ))
         )
      ))

参考

EmacsでフォントにCamingoCodeを使用する

EmacsでCamingoCodeを使用するように設定する. 日本語部分にはRicty Diminishedをあてる.

実行環境

CamingoCode, Ricty Diminishedフォントのインストール

 下記よりそれぞれのフォントをダウンロードし, インストールする.

~/.emacs.d/init.elの設定

 ~/.emacs.d/init.elに下記のように設定を追加する.

 設定方法はOut of Dimension: Emacs のフォント設定を克服するを参考にした.  このサイトでも指摘されている通り, 異なる日本語フォントと英字フォントを組み合わせているため同じフォントサイズでは上手く幅が合わない.  そのため, 日本語フォントと英字フォントのサイズを少しズラして調整する.

;;; CamingoCode + Ricty Diminished
;;;   下記のようなサイズの組み合わせだと全角文字と半角文字のバランスがよい.
;;;   他の組み合わせだとズレるので注意.
;;;     + CamingoCode:size=13, Ricty Diminished:size=14
;;;     + CamingoCode:size=15, Ricty Diminished:size=16
;;;     + CamingoCode:size=17, Ricty Diminished:size=18
(create-fontset-from-ascii-font "CamingoCode:size=13:weight=normal:slant=normal"
                                nil
                                "CamingoCode_RictyDiminished")
(set-fontset-font "fontset-CamingoCode_RictyDiminished"
                  'unicode
                  (font-spec
                   :family "Ricty Diminished"
                   :size 14)
                  nil
                  'append)

;;; 上記で作成したフォントセットをデフォルトに設定する.
(add-to-list 'default-frame-alist '(font . "fontset-CamingoCode_RictyDiminished"))

表示

CamingoCodeはとても素敵.

f:id:boiled_mag:20180522192412p:plain

参考

Windows(MSYS2)でirony-modeをセットアップする

動機

Irony-ModeをWindows環境で使用する方法としてMSYS2を使用するか, MSVCを使用するかを選べるとのことで, 今回はMSYS2を使用してみることにした. Cygwinは…

基本的にSetting up irony mode on Windows · Sarcasm/irony-mode Wiki · GitHubに従って実施したが, MSYS2環境に慣れていなかったために引っかかったところを補足する.

実行環境

  • Windows 10 Pro 64bit版 (バージョン 1703)
  • MSYS2(mingw64)
  • emacs 25.3.1 (x86_64)
  • irony 20180418.1311
  • company-irony 20170905.1346

MSYS2のセットアップ

使用しているMSYS2のバージョン等は下記の通り. MSYS2自体はMSYS2に従ってインストールを実施した.

user@host MINGW64 ~
$ uname -a
MINGW64_NT-10.0 host 2.10.0(0.325/5/3) 2018-02-09 15:25 x86_64 Msys

必要なパッケージのインストール

MSYS2ではpacmanを使用するが下記のコマンドで最新の状態に持っていく. 途中で何度かMSYS2のターミナル(mintty)の再起動が必要になるため, 都度再起動する.

$ pacman -Syuu

ここではGCC, clang, make, CMakeが必要になるため, インストールする. 今回は64bit環境を選んでいるため, 下記のパッケージを使用する.

$ pacman -Suu mingw-w64-x86_64-gcc
$ pacman -Suu mingw-w64-x86_64-clang
$ pacman -Suu mingw-w64-x86_64-cmake
$ pacman -Suu make

Irony-Modeのサーバーバイナリをビルドする

Setting up irony mode on Windows · Sarcasm/irony-mode Wiki · GitHubに従い, サーバーバイナリをビルドする.

最初に実施したときに, pacmanmingw-w64-x86_64-cmakeではなく, cmakeをインストールしたためか「cmake -G "MSYS Makefiles" ..」を実施した際にGeneratorが見つからないとのエラーに遭遇した. 「mingw-w64-x86_64-cmake」をインストールしておけば問題ない. インストールしたパッケージではなく, パッケージによってCMakeのバージョンが「3.10.2-1」と「3.11.1-2」と違っていたためかもしれない.

下記のファイルが出来上がればOK.

irony-mode/server/build/bin/irony-server.exe

Emacsのセットアップ

引き続き手順に従ってEmacsのセットアップを行う. 作成したirony-server.exeを下記に移動する.

~/.emacs.d/irony/bin/irony-server.exe  

irony-modeのインストールにはpackage.elを使用しした. M-x list-packagesから, ironyを選択してインストールすればよい.

設定はuse-packageを利用して下記のようにした. 加えて, 補完のインタフェースにcompanyを使用してるため, company-ironyを合わせてインストールした.

メジャーモードがC/C++のときに設定を有効にする. また, clangに渡すコンパイルオプションに, それぞれC11/C++14を有効にするように指定している.

(setenv "PATH"
        (concat
         "C:\\msys64\\mingw64\\bin" ";"
         (getenv "PATH")))

(setq exec-path (append exec-path '("c:/msys64/mingw64/bin")))

(use-package irony
  :defer t
  :commands irony-mode
  :init
  (add-hook 'c-mode-hook 'irony-mode)
  (add-hook 'c++-mode-hook 'irony-mode)
  :config
  ;; C言語用にコンパイルオプションを設定する.
  (add-hook 'c-mode-hook
            '(lambda ()
               (setq irony-additional-clang-options '("-std=c11" "-Wall" "-Wextra"))))
  ;; C++言語用にコンパイルオプションを設定する.
  (add-hook 'c++-mode-hook
            '(lambda ()
               (setq irony-additional-clang-options '("-std=c++14" "-Wall" "-Wextra"))))
  (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)
  ;; Windows環境でパフォーマンスを落とす要因を回避.
  (when (boundp 'w32-pipe-read-delay)
    (setq w32-pipe-read-delay 0))
  ;; バッファサイズ設定(default:4KB -> 64KB)
  (when (boundp 'w32-pipe-buffer-size)
    (setq irony-server-w32-pipe-buffer-size (* 64 1024)))
  )

(use-package company-irony
  :defer t
  :config
  ;; companyの補完のバックエンドにironyを使用する.
  (add-to-list 'company-backends '(company-irony-c-headers company-irony))
  )

参考

Wiresharkの独自プラグインで既存のDissectorを呼び出す

独自にLuaで定義したプラグイン(Dissector)にてJSON形式データをパースしたかったので, 既存のDissectorを利用した.

下記のように呼び出せばよい.

--
-- プロトコルを作成する.
--
json_proto = Proto("json_proto", "Description: JSON Test Protocol")

-- 名前が長いのでjson_proto.fieldsに別名をつける.
f_json = json_proto.fields

--
-- プロトコルの各フィールドについて型情報, 表示フィルタ, ラベル名等をそれぞれ定義する.
--

-- フレーム境界を認識するためのJSON形式データ長.
f_json.len  = ProtoField.uint32("json_proto.len",  "JSON Data Length", base.DEC)

-- JSON形式データ.
f_json.data = ProtoField.string("json_proto.data", "JSON Data",        base.ASCII)

--
-- 定義したProtoにdissectorという名称の関数を定義する.
--
function json_proto.dissector(buffer, pinfo, tree)
    pinfo.cols.protocol = "JSON Test Protocol"

    local subtree = tree:add(json_proto, buffer(), "JSON Test Protocol")
    local length = buffer(0, 4):uint()

    -- サブツリーに各フィールドを追加する.
    subtree:add(f_json.len,  buffer(0, 4),      length)
    -- ※蛇足だが文字列としても表示しておく.
    subtree:add(f_json.data, buffer(4, length), buffer(4, length):string())

    --
    -- Wireshark組み込みのJSON用のDissectorを呼び出す.
    --
    local json_dissector = Dissector.get("json")
    json_dissector:call(buffer(4, length):tvb(), pinfo, subtree)
end

--
-- 定義したプロトコルとTCPポート 20000 を紐付ける.
--
tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(20000, json_proto)

Wiresharkにこのプラグインを読み込ませ, キャプチャしたパケットを見ると下記のように表示される.

f:id:boiled_mag:20180506151717p:plain
Wiresharkでの表示

参考

11.6. Functions for new protocols and dissectors

LuaAPI/Dissector - The Wireshark Wiki

Rustの開発環境を整える(Windows, Emacs)

前提

  • 2017/8現在の状況で, Windows上のEmacsにてRustの開発環境を整える.
  • 開発のスピードが速く, 以前は必要だった設定が不要になっていることが多い. そのため, 出来るだけメンテナンスされている各ツールのマニュアルに従った方がよい. が, そもそも何をしたのか忘れちゃうので書き残す.
  • 基本的には各ツールのマニュアルに従って設定している.

実行環境

* Windows 10 Pro 64bit版 (バージョン 1703)
* rustup 1.5.0
* rustc 1.19.0
* racer 2.0.10
* cargo 0.20.0

rustupのインストール

Rustのサイトのインストール手順に従ってrustup-init.exeをダウンロードし, rustupをインストールする. これでrustup, rustc, Cargoがインストールされる. 今回はデフォルトのstable-x86_64-pc-windows-msvcを使用する.

https://www.rust-lang.org/ja-JP/install.html

続けてVisual C++ビルドツールが必要になるため, インストールする.

環境変数の確認

Windowsの場合, 環境変数Pathに「%USERPROFILE%.cargo\bin」が追加される. もしされていないようだったら, 自分で追加する.

Racerのインストール

続けて, Racerのインストールを行う. コマンドプロンプト等を起動し, 以下のように実行する.

cargo install racer

CargoはデフォルトだとCPUの数に合わせてコンパイルを並列実行するため, 自分でjobs数を変更してもあまり効果は見られなかった.

Emacsの設定

パッケージのインストール

packages.elを使って下記のパッケージをインストールする. この辺りの手順は省略する.

  • racer
  • flycheck
  • flycheck-rust

この他にも補完にはcompany, エラー表示などにflycheck-popup-tipを使用している.

init.elの設定

設定の記述にはuse-packageを利用した.

;;; rust-mode
(use-package rust-mode
  :defer t
  :config
  (setq rust-format-on-save t))

;;; racer
(use-package racer
  :init
  (add-hook 'rust-mode-hook #'racer-mode)
  (add-hook 'racer-mode-hook #'eldoc-mode))

;;; flycheck-rust
(use-package flycheck-rust
  :init
  (add-hook 'rust-mode-hook
            '(lambda ()
               (flycheck-mode)
               (flycheck-rust-setup))))

設定済み画面

racerによる補完

f:id:boiled_mag:20170815145220p:plain

flycheck + flycheck-popup-tipによるエラー表示

f:id:boiled_mag:20170815145748p:plain

トラブルシューティング

パスの設定などで躓いたときに, 調査で使ったコマンドを残す.

Emacsからracerが正しく実行できているか

  • exec-pathに~/.cargo/binがパスに入っているかどうか.
M-x describe-variable RET exec-path RET
  • 下記のコマンドを実行したときに, 補完の候補が見つかること.
M-! racer complete std::io::B

Proxy内でCargoを使ったツールインストール時のエラー対策(Windows環境)

Cargoを使ってツール(rustfmt, racer)をインストールしようとしたときのメモ。 ユーザ認証が必要なProxy環境でCargoを利用したときに設定した内容を残す。

環境

cargo install racerなどがエラーになる

Proxyを通過出来るように設定してインストールを行おうとしたときに、下記のようなエラーメッセージが表示される。

SSL connect error (schannel: next InitializeSecurityContext failed: Unknown error(0x80092013) - 省略)」

SSL接続時に証明書の失効サーバーへアクセスできないようなので、SSL証明書の失効を確認しないようにする。

設定内容

Cargoをインストールすると%USERPROFILE%(例:c:\Users\user)配下に.cargoフォルダが作成されるので、ここにconfigというファイルを作る。そして以下のように設定を行う。

[http]
    proxy = "http://ユーザ名:パスワード@ホスト名:ポート番号"
    check-revoke = false # SSL証明書の失効を確認しない

Rust自体インストール(Cargo含む)時のProxy設定

Rustの開発環境のインストールはrustupを使って行うが、こちらは環境変数http_proxy、https_proxyを参照するため、予め設定しておく必要がある。下記のページに従ってsetコマンド等で設定するか、環境変数に登録しておく。

rustup.rs/README.md at master · rust-lang-nursery/rustup.rs · GitHub

参考