Jekyll2019-10-23T20:52:22+09:00http://quickhack.net/nom/Quickhack Diarylifehack through quick hack
Yoshinari Nomuraパスワード別送添付メールの話が論文誌に載りました2019-09-21T00:00:00+09:002019-09-21T00:00:00+09:00http://quickhack.net/nom/blog/article-on-ezip-mail-is-published<div id="outline-container-orgad97bac" class="outline-2">
<h2 id="orgad97bac">もう随分前の話ですが</h2>
<div class="outline-text-2" id="text-orgad97bac">
<p>
以前この blog に書いた,パスワード別送添付メールの話が論文になりました.
</p>
<p>
<!-- more -->
</p>
<p>
以前,<a href="2017-11-06-password-is-in-another-mail.html">「パスワードは別途お送りします」をなんとかしたい</a> で glima について書きました.
その話を情報処理学会で発表したら,<a href="https://www.ipsj.or.jp/award/yamashita2018.html">山下記念研究賞</a>をいただきました.
</p>
<p>
パスワード別送添付メールの問題は,今日では広く認知されていると感じます.
問題解消の動きの一助になったとしたら,嬉しいです.
</p>
<p>
発表後,論文誌にも推薦していただき,無事掲載.何と<a href="https://www.ipsj.or.jp/award/ssp_award.html#anc1">特選論文</a>にも選ばれました.
論文の PDF と関連するリンクをまとめておきます.
<a href="https://github.com/yoshinari-nomura/glima">GitHub</a> のスターも論文同様,嬉しいものです.
</p>
</div>
</div>
<div id="outline-container-org7ef814c" class="outline-2">
<h2 id="org7ef814c">関連リンク</h2>
<div class="outline-text-2" id="text-org7ef814c">
<ul class="org-ul">
<li>Blog: <a href="http://quickhack.net/nom/blog/2017-11-06-password-is-in-another-mail.html">「パスワードは別途お送りします」をなんとかしたい</a></li>
<li>GitHub: <a href="https://github.com/yoshinari-nomura/glima">yoshinari-nomura/glima: Gmail CLI client</a></li>
<li>Slideshare: <a href="https://www.slideshare.net/nomlab/ss-85329306">そのメール,ホントに暗号化が必要ですか?</a></li>
<li>論文PDF: <a href="dat/doc/glima-paper.pdf">パスワード別送添付メールの問題点と受信側での対策について</a> (著作権は情報処理学会に帰属します.取り扱いについては,<a href="http://www.ipsj.or.jp/copyright/ronbun/copyright.html#chui">こちら</a>)</li>
</ul>
</div>
</div>Yoshinari Nomuraもう随分前の話ですが 以前この blog に書いた,パスワード別送添付メールの話が論文になりました.Build Rust environment for ESP322019-05-14T00:00:00+09:002019-05-14T00:00:00+09:00http://quickhack.net/nom/blog/build-rust-environment-for-esp32<div id="outline-container-org097e70d" class="outline-2">
<h2 id="org097e70d">What is it?</h2>
<div class="outline-text-2" id="text-org097e70d">
<p>
Recently I heard that LLVM for xtensa is working, so I tried to build Rust for ESP32.
</p>
<p>
(2019-05-16 Translated into English)
<!-- more -->
</p>
<p>
Source information is, <a href="https://gist.github.com/MabezDev/26e175790f84f2f2b0f9bca4e63275d1">here</a> and <a href="https://esp32.com/viewtopic.php?t=9226">here</a>.
</p>
</div>
</div>
<div id="outline-container-org0fa653a" class="outline-2">
<h2 id="org0fa653a">Environment</h2>
<div class="outline-text-2" id="text-org0fa653a">
<ul class="org-ul">
<li>Ubuntu 18.04 LTS</li>
<li>esp-idf commit_id 5c88c5996dbde6208e3bec05abc21ff6cd822d26</li>
</ul>
</div>
</div>
<div id="outline-container-orge8bce51" class="outline-2">
<h2 id="orge8bce51">Build LLVM</h2>
<div class="outline-text-2" id="text-orge8bce51">
<div class="org-src-container">
<pre class="src src-shell-script">sudo apt-get install ninja-build
<span class="org-builtin">export</span> <span class="org-variable-name">MY_BUILD_ROOT</span>=<span class="org-string">"$HOME/.xtensa"</span>
mkdir -p <span class="org-string">"$MY_BUILD_ROOT"</span>
<span class="org-builtin">cd</span> <span class="org-string">"$MY_BUILD_ROOT"</span>
git clone https://github.com/espressif/llvm-xtensa.git
git clone https://github.com/espressif/clang-xtensa.git llvm-xtensa/tools/clang
mkdir llvm_build
<span class="org-builtin">cd</span> llvm_build
<span class="org-comment-delimiter"># </span><span class="org-comment">from https://gist.github.com/MabezDev/26e175790f84f2f2b0f9bca4e63275d1</span>
cmake ../llvm-xtensa -DLLVM_TARGETS_TO_BUILD=<span class="org-string">"Xtensa;X86"</span> -DCMAKE_BUILD_TYPE=Release -G <span class="org-string">"Ninja"</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">Take a while</span>
cmake --build .
</pre>
</div>
</div>
</div>
<div id="outline-container-orgcedd54f" class="outline-2">
<h2 id="orgcedd54f">Check clang is working</h2>
<div class="outline-text-2" id="text-orgcedd54f">
<div class="org-src-container">
<pre class="src src-shell-script"> <span class="org-builtin">cd</span> <span class="org-string">"$MY_BUILD_ROOT"</span>
cat <<EOF > test.c
<span class="org-sh-heredoc"> int main() {</span>
<span class="org-sh-heredoc"> printf("Hello world\n");</span>
<span class="org-sh-heredoc"> }</span>
<span class="org-sh-heredoc"> EOF</span>
./llvm_build/bin/clang -target xtensa -fomit-frame-pointer -S test.c -o test.S
xtensa-esp32-elf-as test.S
file a.out
<span class="org-comment-delimiter"># </span><span class="org-comment">→ a.out: ELF 32-bit LSB relocatable, Tensilica Xtensa, version 1 (SYSV), not stripped</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgbd83a73" class="outline-2">
<h2 id="orgbd83a73">Bulid rustc</h2>
<div class="outline-text-2" id="text-orgbd83a73">
<div class="org-src-container">
<pre class="src src-shell-script"><span class="org-builtin">cd</span> <span class="org-string">"$MY_BUILD_ROOT"</span>
git clone git@github.com:MabezDev/rust-xtensa.git
<span class="org-builtin">cd</span> rust-xtensa
mkdir <span class="org-string">"$MY_BUILD_ROOT/rust_build"</span>
./configure --llvm-root=<span class="org-string">"$MY_BUILD_ROOT/llvm_build"</span> --prefix=<span class="org-string">"$MY_BUILD_ROOT/rust_build"</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">python 2 is required.</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">seems to clone something. before help is invoked.</span>
python ./x.py --help
<span class="org-comment-delimiter"># </span><span class="org-comment">Take a while</span>
python ./x.py build
python ./x.py install
</pre>
</div>
</div>
</div>
<div id="outline-container-org3f5cf37" class="outline-2">
<h2 id="org3f5cf37">Check rustc is working</h2>
<div class="outline-text-2" id="text-org3f5cf37">
<p>
Does rustc support xtensa?
</p>
<div class="org-src-container">
<pre class="src src-shell-script"><span class="org-string">"$MY_BUILD_ROOT/rust_build/bin/rustc"</span> --print target-list | grep xtensa
<span class="org-comment-delimiter"># </span><span class="org-comment">→ xtensa-none-elf</span>
</pre>
</div>
<p>
Register own xtensa rustc to rustup
</p>
<div class="org-src-container">
<pre class="src src-shell-script">rustup toolchain link xtensa <span class="org-string">"$MY_BUILD_ROOT/rust_build"</span>
rustup run xtensa rustc --print target-list | grep xtensa
<span class="org-comment-delimiter"># </span><span class="org-comment">→ xtensa-none-elf</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgb5685ec" class="outline-2">
<h2 id="orgb5685ec">Build a sample project</h2>
<div class="outline-text-2" id="text-orgb5685ec">
<div class="org-src-container">
<pre class="src src-shell-script">git clone git@github.com:lexxvir/esp32-hello.git
<span class="org-builtin">cd</span> esp32-hello
rmdir esp-idf
ln -s $<span class="org-variable-name">IDF_PATH</span> esp-idf
</pre>
</div>
<p>
Manipulate .carg/config to work with your esp-idf environment.
</p>
<div class="org-src-container">
<pre class="src src-diff"><span class="org-diff-context">diff --git a/.cargo/config b/.cargo/config</span>
<span class="org-diff-context">index f7c9d09..04a57ef 100644</span>
<span class="org-diff-header">--- </span><span class="org-diff-header"><span class="org-diff-file-header">a/.cargo/config</span></span>
<span class="org-diff-header">+++ </span><span class="org-diff-header"><span class="org-diff-file-header">b/.cargo/config</span></span>
<span class="org-diff-hunk-header">@@ -3,6 +3,7 @@</span><span class="org-diff-function"> target = "xtensa-none-elf"</span>
<span class="org-diff-context"> [target.xtensa-none-elf]</span>
<span class="org-diff-context"> rustflags = [</span>
<span class="org-diff-indicator-added">+</span><span class="org-diff-added"> "-C", "target-cpu=esp32",</span>
<span class="org-diff-context"> "-C", "save-temps",</span>
<span class="org-diff-context"> "-C", "link-arg=-nostdlib",</span>
<span class="org-diff-hunk-header">@@ -25,7 +26,7 @@</span><span class="org-diff-function"> rustflags = [</span>
<span class="org-diff-context"> "-C", "link-arg=-Lesp-idf/components/esp32/ld",</span>
<span class="org-diff-context"> "-C", "link-arg=-Tesp32_out.ld",</span>
<span class="org-diff-indicator-removed">-</span><span class="org-diff-removed"> "-C", "link-arg=-Tbuild/esp32/esp32.project.ld",</span>
<span class="org-diff-indicator-added">+</span><span class="org-diff-added"> "-C", "link-arg=-Tbuild/esp32/esp32.common.ld",</span>
<span class="org-diff-context"> "-C", "link-arg=-Tesp32.rom.ld",</span>
<span class="org-diff-context"> "-C", "link-arg=-Tesp32.peripherals.ld",</span>
"-C", "link-arg=-Tesp32.rom.libgcc.ld",
</pre>
</div>
<p>
add XARGO_RUST_SRC to setenv.sh
</p>
<div class="org-src-container">
<pre class="src src-shell-script"><span class="org-builtin">echo</span> <span class="org-string">"export XARGO_RUST_SRC='$MY_BUILD_ROOT/rust-xtensa/src'"</span> >> setenv.sh
</pre>
</div>
<p>
Modify build.sh to use <code>rustup run xtensa xargo</code>
</p>
<div class="org-src-container">
<pre class="src src-diff"><span class="org-diff-context">diff --git a/build.sh b/build.sh</span>
<span class="org-diff-context">index e7bcb40..70be266 100755</span>
<span class="org-diff-header">--- </span><span class="org-diff-header"><span class="org-diff-file-header">a/build.sh</span></span>
<span class="org-diff-header">+++ </span><span class="org-diff-header"><span class="org-diff-file-header">b/build.sh</span></span>
<span class="org-diff-hunk-header">@@ -5,7 +5,7 @@</span><span class="org-diff-function"> source setenv.sh</span>
<span class="org-diff-context"> # export V=1</span>
<span class="org-diff-context"> make -j6 app</span>
<span class="org-diff-indicator-removed">-</span><span class="org-diff-removed">cargo build --release #--verbose</span>
<span class="org-diff-indicator-added">+</span><span class="org-diff-added">rustup run xtensa xargo build --release #--verbose</span>
<span class="org-diff-context"> $IDF_PATH/components/esptool_py/esptool/esptool.py \</span>
--chip esp32 \
</pre>
</div>
<p>
Build the sample. <code>target/xtensa-none-elf/release/esp32-hello.bin</code> will appear if successfull.
</p>
<div class="org-src-container">
<pre class="src src-shell-script">./build.sh
ls target/xtensa-none-elf/release/esp32-hello.bin
<span class="org-comment-delimiter"># </span><span class="org-comment">→ target/xtensa-none-elf/release/esp32-hello.bin</span>
</pre>
</div>
<p>
Flash it.
</p>
<div class="org-src-container">
<pre class="src src-shell-script">python $<span class="org-variable-name">IDF_PATH</span>/components/esptool_py/esptool/esptool.py <span class="org-sh-escaped-newline">\</span>
--chip esp32 --port /dev/ttyUSB0 --baud 115200 <span class="org-sh-escaped-newline">\</span>
--before default_reset --after hard_reset write_flash -z --flash_mode dio <span class="org-sh-escaped-newline">\</span>
--flash_freq 40m --flash_size detect 0x1000 build/bootloader/bootloader.bin 0x10000 <span class="org-sh-escaped-newline">\</span>
target/xtensa-none-elf/release/esp32-hello.bin <span class="org-sh-escaped-newline">\</span>
0x8000 build/partitions_singleapp.bin
</pre>
</div>
<p>
Connect a LED to GPIO2, you will see the LED is blinking.
</p>
</div>
</div>Yoshinari NomuraWhat is it? Recently I heard that LLVM for xtensa is working, so I tried to build Rust for ESP32.第二種電気工事士の免許を取るには2019-03-17T00:00:00+09:002019-03-17T00:00:00+09:00http://quickhack.net/nom/blog/how-to-get-electric-work-specialist-license<div id="outline-container-orgc384d58" class="outline-2">
<h2 id="orgc384d58">はじめに</h2>
<div class="outline-text-2" id="text-orgc384d58">
<p>
もう去年の夏のことになってしまいましたが,第二種電気工事士の免許取得についてメモを残しておこうと思います.
</p>
<p>
<!-- more -->
</p>
</div>
</div>
<div id="outline-container-orgd2aa1a8" class="outline-2">
<h2 id="orgd2aa1a8">第二種電気工事士って?</h2>
<div class="outline-text-2" id="text-orgd2aa1a8">
<p>
この免許を取ると何ができるのかというのは,以下のページに概要が書いてあります.
</p>
<ul class="org-ul">
<li><a href="https://www.shiken.or.jp/construction.html">電気工事士って何だろう? | ECEE 一般財団法人電気技術者試験センター</a></li>
</ul>
<p>
僕の場合,家の壁のコンセントを自分で取り換えたり,埋め込み式の電灯を増設したいというのが主な動機でした.
</p>
</div>
</div>
<div id="outline-container-org93131f8" class="outline-2">
<h2 id="org93131f8">試験について</h2>
<div class="outline-text-2" id="text-org93131f8">
<p>
第二種は,年2回試験があって,上期は6月初旬,下期は10月初旬に筆記試験があります.
筆記に合格すると,2ヶ月程先に技能試験があります.
</p>
<p>
受験申込はネットからできますが,締切が早いので気をつけましょう.
平成31年度の申込は,<a href="https://uketsuke.shiken.or.jp/mohshi/FIC1010.do">もうはじまって</a>ますね.
</p>
<p>
筆記試験は,マークシート式で,60点が合格ラインといわれています.
「オームの法則って何?」 という人は,少々勉強が必要ですが,
ある程度電気の素養がある人は,それほど苦労なくパスできるでしょう.
僕 (電子工学科卒業) の場合,週末を潰して丸 2日ぐらいの勉強で 80点ぐらい取れました.
</p>
<p>
技能試験は,割と真面目に練習しないと受からないと思います.あらかじめ配線図が公開された候補問題(13問)があって,
当日その内の1問が出るので,40分をかけて完成させるという問題です.13問のなかに基本の配線技術が含まれていて,
一通りできるようになっていないと受かりません.工事士免許という性格を反映してる,よくできた試験だと思いました.
僕の場合,2週間弱,夜帰宅後に1時間程度練習したと思います.
</p>
</div>
</div>
<div id="outline-container-orgf981742" class="outline-2">
<h2 id="orgf981742">参考書や買ったもの</h2>
<div class="outline-text-2" id="text-orgf981742">
<p>
学科は,これ1冊で大丈夫でした.電気技術者試験センターのサイトにも過去問があります.
</p>
<ul class="org-ul">
<li><a href="https://www.amazon.co.jp/dp/4297101637">2019年版 第二種電気工事士試験 完全攻略 筆記試験編</a></li>
</ul>
<p>
技能試験では,以下の本の他に DVD や Youtube の動画が参考になりました.
</p>
<ul class="org-ul">
<li><p>
<a href="https://www.amazon.co.jp/dp/4297104520">2019年版 第二種電気工事士試験 完全攻略 技能試験編</a>
</p>
<p>
カラーで一問づつ丁寧に解説しているのでよかったです.
技能試験では,一発アウトになる,「やってはいけない事」があり,それの一覧がまとめられていて,よい確認になりました.
また,技能試験の配線の寸法取りには,独特のルールみたいなものがあるらしく,その感覚が参考になりました.
</p></li>
</ul>
<p>
技能試験用に工具と部材も揃えました.
</p>
<ul class="org-ul">
<li><p>
<a href="https://www.amazon.co.jp/dp/B079ZWGTJY">電気工事士技能試験工具セット 基本工具+P-958VVFストリッパー DK-28 特典ハンドブック付</a>
</p>
<p>
おそらく,これは年度代わっても同じ物でOKだと思います.P-958 VVFストリッパーが便利です.
DK-18 (基本工具 + P-958 VVFストリッパー付き) がいいと思いますが,
何故か受験対策用の DVD が付いた DK-28 のほうが安くなっていますね.
</p>
<p>
技能試験は,電動工具以外の工具なら大体何でも持ち込んでいいので,
ちょっと高いですが,便利な工具を一式揃えるのがおすすめです.
</p></li>
<li><p>
<a href="https://www.amazon.co.jp/dp/B079JG1MD1">平成31年 第二種電気工事士技能試験 練習用部材 DK-51 1回セット 特典ハンドブック・DVD付</a>
</p>
<p>
これに付いてる DVD で基本操作を覚えました.部材は,1回分とありますが,
候補問題の13問を1回づつこなせるという意味です.かなり余裕があるので,これ1つで十分だと思います.
これを使い切る頃には,ホームセンターで不足部材だけを安くを買えるような知識が身に付いていると思います.
</p></li>
</ul>
</div>
</div>
<div id="outline-container-org784efe7" class="outline-2">
<h2 id="org784efe7">技能試験に関するメモ</h2>
<div class="outline-text-2" id="text-org784efe7">
<p>
技能試験勉強の過程と受験後の感想をメモとして残しておきたいと思います.
</p>
<ul class="org-ul">
<li>複線図を書かないで,その場でクリップ等で縛りながら配線するのが効率的.
<ul class="org-ul">
<li>複線図を書ける能力は,必要だが,本番で実際に書く必要はない.</li>
<li>なぜなら,複線図を書いても,それと実体の配線の対応を取る手間がかえって面倒.</li>
</ul></li>
<li>全部の線をバンバン切ってから配線するのではなく,切りつつ小物毎に作っていく.
<ul class="org-ul">
<li>線の長さを切り間違いにくいし,間違いに気付いても修正しやすい.</li>
<li>線を切って並べておくと,何がどの線だったか分からなくなって混乱する.</li>
</ul></li>
<li><p>
寸法取りの基本 (HOZAN P-958 を使うことが前提.普通のペンチだと加工のために長く取る必要があるかも)
</p>
<table>
<colgroup>
<col class="org-left">
<col class="org-left">
<col class="org-left">
<col class="org-left">
<col class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">取付用具</th>
<th scope="col" class="org-left">寸法取</th>
<th scope="col" class="org-left">外被覆剥</th>
<th scope="col" class="org-left">内被覆剥</th>
<th scope="col" class="org-left">備考</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">VFFボックス</td>
<td class="org-left">+10cm</td>
<td class="org-left">10cm</td>
<td class="org-left">2cm or 1.2cm</td>
<td class="org-left">内被覆剥はリングスリーブ or ボックスコネクタに依存</td>
</tr>
<tr>
<td class="org-left">埋込用器具</td>
<td class="org-left">+5cm</td>
<td class="org-left"><b>10cm</b></td>
<td class="org-left">1cm or 1.2cm</td>
<td class="org-left">間違いやすい.内被覆剥は器具のゲージによる.</td>
</tr>
<tr>
<td class="org-left">ランプ(R)</td>
<td class="org-left">+5cm</td>
<td class="org-left">4.5cm</td>
<td class="org-left">2.5cm</td>
<td class="org-left">内被覆を 2cm残す</td>
</tr>
<tr>
<td class="org-left">露出コンセント</td>
<td class="org-left">+5cm</td>
<td class="org-left">3.5cm</td>
<td class="org-left">2.5cm</td>
<td class="org-left">内被覆を 1cm残す</td>
</tr>
<tr>
<td class="org-left">引掛シーリング</td>
<td class="org-left">+2cm</td>
<td class="org-left">ゲージ</td>
<td class="org-left">ゲージ</td>
<td class="org-left">寸法取りのとき注意</td>
</tr>
<tr>
<td class="org-left">ブレーカ/端子台</td>
<td class="org-left">+0cm</td>
<td class="org-left">5cm</td>
<td class="org-left">1.2cm</td>
<td class="org-left">内被覆剥は,逐次合わせるのが無難.端子台もこれ.</td>
</tr>
</tbody>
</table></li>
<li>圧着で束ねる線の太さと本数 vs 使用するリングスリーブの大きの関係
<ul class="org-ul">
<li>1.6mm x 2本 に限り「極小」</li>
<li>1.6mm x 4本までは「小」それを越えると「中」</li>
<li>2.0mm は,1.6mm x 2本に換算しれ上のルールを適用する</li>
</ul></li>
<li>試験開始後の図面の確認で重要なこと
<ul class="org-ul">
<li>図面には,まず,切断寸法と,リングスリーブ/ボックスコネクタのどちらを使うかを記入しておく
<ul class="org-ul">
<li>線を剥くときに,ボックスとリングのどちらかによって 2cm or 1.2cm を変えると効率的だから.</li>
</ul></li>
<li>スイッチと器具の関係をよく確認する.</li>
<li>線の種類 (1.6mm or 2.0mm, 2芯 or 3芯 等) をよく確認する.VVF でない線がある場合は,特に注意.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orge629fba" class="outline-2">
<h2 id="orge629fba">感想</h2>
<div class="outline-text-2" id="text-orge629fba">
<p>
受験を終えて思ったことは,
</p>
<ul class="org-ul">
<li>電気工事士の試験は,よくできていると思う.特に実技.やるべきことをやらないと受からないようになっている.
実施する側は大変だろうなとも思った.</li>
<li>実技に一度落ちた.自分ではできたつもりだったが,なぜ落ちたかのフィードバックがないので困惑した.</li>
<li>ホームセンターで VVF線やコネクタを買い足してみたが,終わってみれば必要はなかったかも.</li>
<li>ホーザンの実技1回分セットと工具セット,付属の教習ビデオがすごく役立った.</li>
<li>参考書は学科と実技で1種類買えば十分だと思った.</li>
<li>平日の夜,仕事終わってからリビングのテーブルで練習するのは,辛い.家族の理解が必要.</li>
<li>今になって思えば,基本操作を磨くのが重要.
<a href="https://www.hozan.co.jp/denko/tool/product/P-958.html">製品詳細【VVFストリッパー P-958】 | 第二種電工試験の虎</a> を見て練習するだけでもタメになった.</li>
<li><p>
技能試験では,複線図を書かなかった.このやり方は,以下の Youtube を参考にした.
</p>
<ul class="org-ul">
<li><a href="https://www.youtube.com/watch?v=xzYdunMdhP0">2015第二種電気工事士技能試験 実体複線図 電気工事士奪取プロジェクト6 - YouTube</a></li>
</ul>
<p>
自分でも複線図を一々書くのは面倒だと薄々思っていたけど,
参考書には必ず複線図を書くように書いてあったので,最初真面目に書いていたが,この動画に救われた.
また,実体複線図の話がすごく参考になった.インシュロックを使う方法,
マジックで印を付けておいたほうがいいかというのも参考になる.
</p></li>
<li>Youtube で実際のものを見られるようになったのは,いい時代だ.
でも,そばに同士がいないのは辛いし,先生がいてフィードバックがあれば,
もっと効率がよかっただろう.学校ってそういうところだなと思った.</li>
</ul>
</div>
</div>Yoshinari Nomuraはじめに もう去年の夏のことになってしまいましたが,第二種電気工事士の免許取得についてメモを残しておこうと思います.My USB Type-C Equipment2018-04-15T00:00:00+09:002018-04-15T00:00:00+09:00http://quickhack.net/nom/blog/my-usb-type-c-equipment<div id="outline-container-orgac094aa" class="outline-2">
<h2 id="orgac094aa">USB Type-C はじめました</h2>
<div class="outline-text-2" id="text-orgac094aa">
<p>
少し前から MacBook Pro 13" (2017) を使用中です.15" より機動力は上がったのですが,
キーボードで指が痛くなるのが玉に瑕です.もう1つ大きな変化は,USB Type-C になったことです.
おすすめの USB Type-C 製品を聞かれて「そのうちブログにでも書くよと」いって放置していたので,
反省して紹介しておきたいと思います.
</p>
<p>
<!-- more -->
</p>
</div>
</div>
<div id="outline-container-orgf8d4033" class="outline-2">
<h2 id="orgf8d4033">おすすめの USB Type-C 製品</h2>
<div class="outline-text-2" id="text-orgf8d4033">
<p>
Type-C は,結論として,すこぶる快適です.ケーブルの向きを間違えてイライラしないで済みますし,
出張時の荷物を減らすことに血道を上げている僕としては,
装備がコンパクトになるのが大変嬉しいです.
</p>
<p>
特に充電器は,アップル純正以外の物が豊富,軽量で安価なのがいいですね.
僕も純正品は,デスクに置いて,軽い充電器を持ち歩いています.
</p>
<p>
以下,自分で使ってみたおすすめです.購入から少し時間が経っているので,
もっと良い物が出ているかもしれません.
また, <b>信じて購入されて,不具合などがあったとしても,責任は取れませんので,あしからず</b>.
</p>
</div>
<div id="outline-container-org303a25b" class="outline-3">
<h3 id="org303a25b">充電器とケーブル</h3>
<div class="outline-text-3" id="text-org303a25b">
<ul class="org-ul">
<li><p>
<a href="https://www.amazon.co.jp/dp/B071R6ZF41/">Anker PowerPort Speed 1 PD30 (30W USB-C急速充電器)</a>
</p>
<p>
安心の Anker.30W なので,充電が遅いのでは? と心配しましたが,僕は不満ありません.
なにしろ軽くてコンパクト.いつも鞄に入れています.スマホと共用できるのもいいです.
</p></li>
<li><p>
<a href="https://www.amazon.co.jp/dp/B071XYBPMN/">Anker PowerLine+ USB-C & USB-C 2.0 ケーブル (0.9m)</a>
</p>
<p>
細くて柔軟で丈夫,見ためもいいので気に入っています.主に出先での充電用途.
転送スピードが欲しい人は注意.
</p></li>
<li><p>
<a href="https://www.amazon.co.jp/gp/product/B01MG9JIIF/">AUKEY カーチャージャー 36W USB Type-C</a>
</p>
<p>
滅多に使わないですが,車に 1個置いておくと,安心.
</p></li>
</ul>
</div>
</div>
<div id="outline-container-org4cf3d64" class="outline-3">
<h3 id="org4cf3d64">USB ハブ / 変換アダプタ</h3>
<div class="outline-text-3" id="text-org4cf3d64">
<ul class="org-ul">
<li><p>
<a href="https://www.amazon.co.jp/dp/B075P3CR6V/">USB Type-C Hub HDMI/2*USB 3.0/SDカード/MicroSDカードリーダ</a>
</p>
<p>
安価でコンパクト,スッキリとしたデザインで気に入っています.これ1つ鞄に入れておけば,
大抵,用が足ります.
</p></li>
<li><p>
<a href="https://www.amazon.co.jp/dp/B01N0O7NAT/">Anker USB-C & HDMI 変換アダプター</a>
</p>
<p>
HDMI に出力するだけなら,こちらのほうがコンパクト.主にオフィスではこちらを使っています.
</p></li>
<li><p>
<a href="https://www.amazon.co.jp/dp/B01GNXN2VQ/">IDEAPRO HDMI to VGA変換アダプター</a>
</p>
<p>
HDMI だけで生活できればいいのですが,たまに VGA が必要になることも.
上記 2つの HDMI ポートにこれを繋ぐことで VGA に変換できています.
オーディオジャックは使ったことがありません.
</p></li>
<li><p>
<a href="https://www.amazon.co.jp/dp/B01EL4PVFE/">Rankie USB C 変換アダプター</a>
</p>
<p>
2個セットで安いので買ってみました.問題なく使えています.意外とよく使うので,もう1セット欲しいかも.
</p></li>
<li><p>
<a href="https://www.amazon.co.jp/dp/B001MQBRJE/">iBUFFALO カードリーダー/ライター microSD対応 超コンパクト</a>
</p>
<p>
Type-C 製品ではないですが,これと Rankie USB C 変換アダプターをつないだ状態で持ち歩くと,
Type-C の USB メモリとして使えるので便利です.Type-C USB メモリを買うより便利だと思います.
</p></li>
</ul>
</div>
</div>
<div id="outline-container-org9edb1da" class="outline-3">
<h3 id="org9edb1da">持ってないけど良さそう</h3>
<div class="outline-text-3" id="text-org9edb1da">
<p>
以下は,自分では試したことがありません.
</p>
<ul class="org-ul">
<li><p>
<a href="https://www.amazon.co.jp/dp/B01007BR2W/">Anker USB-C & イーサネットアダプタ</a>
</p>
<p>
今後,有線が欲しい場合もあるので1つは持っておきたいところ.
</p></li>
<li><p>
<a href="https://www.amazon.co.jp/dp/B072KBL74F/">Anker 5-in-1 プレミアム USB-Cハブ (3*USB3.0 / HDMI / 1Gbpsイーサ)</a>
</p>
<p>
少し高価だけど,有線と HDMI が使えるので,これを持ち歩くのもアリかも.
</p></li>
</ul>
</div>
</div>
</div>Yoshinari NomuraUSB Type-C はじめました 少し前から MacBook Pro 13" (2017) を使用中です.15" より機動力は上がったのですが, キーボードで指が痛くなるのが玉に瑕です.もう1つ大きな変化は,USB Type-C になったことです. おすすめの USB Type-C 製品を聞かれて「そのうちブログにでも書くよと」いって放置していたので, 反省して紹介しておきたいと思います.Enable TCP keepalive of macOS and Linux in Ruby2018-01-19T00:00:00+09:002018-01-19T00:00:00+09:00http://quickhack.net/nom/blog/enable-tcp-keepalive-of-macos-and-linux-in-ruby<div id="outline-container-org437e8c4" class="outline-2">
<h2 id="org437e8c4">はじめに</h2>
<div class="outline-text-2" id="text-org437e8c4">
<p>
TCP keepalive を使ったプログラムを Ruby で書こうとしてはまったので,メモです.
<!-- more -->
</p>
</div>
</div>
<div id="outline-container-org3abb048" class="outline-2">
<h2 id="org3abb048">TCP keepalive とは</h2>
<div class="outline-text-2" id="text-org3abb048">
<p>
TCP (ソケット) を使って pub/sub 形式のサービスに接続して,サーバからのイベントを待っていたとします.
その際,サーバからのデータがしばらく届かない状態が続くと,単にイベントがないだけなのか,
セッションが切れてしまっているのかを知ることができません.
そこで,何の用事がなくても一定時間毎に空パケットを相手に送って返信を貰うことで,
セッションの維持を確認するのが TCP keepalive です.
</p>
<p>
ちなみに,Websocket にも,ping/pong という仕組みがあり,
同様の事をより上のレイヤで実現しようとしている例です.
Slack や IRC もアプリケーションのレイヤで ping/pong の仕組みを持っています.
</p>
<p>
また,HTTP にも keepalive と呼ばれる仕組みがありますが,上記の類とは別物で目的も違います.
</p>
</div>
</div>
<div id="outline-container-org79dec2f" class="outline-2">
<h2 id="org79dec2f">TCP keepalive を設定するには</h2>
<div class="outline-text-2" id="text-org79dec2f">
<p>
TCP keepalive がデフォルト有効かどうかは OS 次第のようですが,
有効であっても,タイムアウトが 2時間といった状態なので,
目的に応じてセッション (ソケット) 毎に時間を設定したほうがいいでしょう.
</p>
<p>
C言語だと,こんな感じです.Linux の <code>TCP_KEEPIDLE</code> に相当するものは,
macOS (Darwin) では, <code>TCP_KEEPALIVE</code> となっているので注意が必要です.これではまりました.
</p>
<div class="org-src-container">
<pre class="src src-c"><span class="org-preprocessor">#include</span> <span class="org-string"><sys/socket.h></span>
<span class="org-preprocessor">#include</span> <span class="org-string"><netinet/in.h></span>
<span class="org-preprocessor">#include</span> <span class="org-string"><netinet/tcp.h></span>
<span class="org-comment-delimiter">/* </span><span class="org-comment">macOS (Darwin) uses TCP_KEEPALIVE, while Linux uses TCP_KEEPIDLE </span><span class="org-comment-delimiter">*/</span>
<span class="org-preprocessor">#if</span> <span class="org-preprocessor">defined</span>(__APPLE__) && <span class="org-preprocessor">defined</span>(__MACH__)
<span class="org-preprocessor"># define</span> <span class="org-variable-name">TCP_KEEPIDLE</span> TCP_KEEPALIVE
<span class="org-preprocessor">#endif</span>
<span class="org-type">void</span> <span class="org-function-name">setsockopt_test</span>(<span class="org-type">int</span> <span class="org-variable-name">socket</span>)
{
<span class="org-comment-delimiter">/* </span><span class="org-comment">After 40-sec silence, send 2 keepalives with 10-sec interval </span><span class="org-comment-delimiter">*/</span>
<span class="org-type">int</span> <span class="org-variable-name">enable</span> = 1; <span class="org-comment-delimiter">/* </span><span class="org-comment">set keepalive on/off </span><span class="org-comment-delimiter">*/</span>
<span class="org-type">int</span> <span class="org-variable-name">idle</span> = 40; <span class="org-comment-delimiter">/* </span><span class="org-comment">idle time used when SO_KEEPALIVE is enabled </span><span class="org-comment-delimiter">*/</span>
<span class="org-type">int</span> <span class="org-variable-name">intvl</span> = 10; <span class="org-comment-delimiter">/* </span><span class="org-comment">interval between keepalives </span><span class="org-comment-delimiter">*/</span>
<span class="org-type">int</span> <span class="org-variable-name">keepcnt</span> = 2; <span class="org-comment-delimiter">/* </span><span class="org-comment">number of keepalives before close </span><span class="org-comment-delimiter">*/</span>
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &enable, <span class="org-keyword">sizeof</span>(enable));
setsockopt(socket, IPPROTO_TCP, TCP_KEEPIDLE, &idle, <span class="org-keyword">sizeof</span>(idle));
setsockopt(socket, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, <span class="org-keyword">sizeof</span>(intvl));
setsockopt(socket, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, <span class="org-keyword">sizeof</span>(keepcnt));
}
</pre>
</div>
<p>
Ruby だと:
</p>
<div class="org-src-container">
<pre class="src src-ruby"><span class="org-builtin">require</span> <span class="org-string">'socket'</span>
<span class="org-type">MY_TCP_KEEPIDLE</span> = <span class="org-keyword">if</span> <span class="org-type">RUBY_PLATFORM</span> =~ <span class="org-string">/darwin/</span> <span class="org-keyword">then</span> 0x10 <span class="org-keyword">else</span> <span class="org-constant">:TCP_KEEPIDLE</span> <span class="org-keyword">end</span>
<span class="org-keyword">def</span> <span class="org-function-name">set_tcp_keepalive</span>(sock)
<span class="org-comment-delimiter"># </span><span class="org-comment">After 40-sec silence, send 2 keepalives with 10-sec interval</span>
enable = <span class="org-constant">true</span> <span class="org-comment-delimiter"># </span><span class="org-comment">set keepalive on/off</span>
idle = 40 <span class="org-comment-delimiter"># </span><span class="org-comment">idle time used when SO_KEEPALIVE is enabled</span>
intvl = 10 <span class="org-comment-delimiter"># </span><span class="org-comment">interval between keepalives</span>
keepcnt = 2 <span class="org-comment-delimiter"># </span><span class="org-comment">number of keepalives before close</span>
sock.setsockopt(<span class="org-constant">:SOL_SOCKET</span>, <span class="org-constant">:SO_KEEPALIVE</span>, enable)
sock.setsockopt(<span class="org-constant">:IPPROTO_TCP</span>, <span class="org-type">MY_TCP_KEEPIDLE</span>, idle)
sock.setsockopt(<span class="org-constant">:IPPROTO_TCP</span>, <span class="org-constant">:TCP_KEEPINTVL</span>, intvl)
sock.setsockopt(<span class="org-constant">:IPPROTO_TCP</span>, <span class="org-constant">:TCP_KEEPCNT</span>, keepcnt)
<span class="org-keyword">end</span>
</pre>
</div>
<p>
どうやら,macOS 用の <code>TCP_KEEPALIVE</code> をシンボルで受け付けないようです.これではまりました.
行儀が悪いですが,0x10 を直接渡しています.(何かいい方法はないのでしょうか?)
ちなみに 0x10 は, <code>/usr/include/netinet/tcp.h</code> から調べました:
</p>
<div class="org-src-container">
<pre class="src src-c"><span class="org-comment-delimiter">// </span><span class="org-comment">macOS 10.12.6 (Sierra) /usr/include/netinet/tcp.h</span>
<span class="org-preprocessor">#define</span> <span class="org-variable-name">TCP_KEEPALIVE</span> 0x10 <span class="org-comment-delimiter">/* </span><span class="org-comment">idle time used when SO_KEEPALIVE is enabled </span><span class="org-comment-delimiter">*/</span>
<span class="org-preprocessor">#define</span> <span class="org-variable-name">TCP_KEEPINTVL</span> 0x101 <span class="org-comment-delimiter">/* </span><span class="org-comment">interval between keepalives </span><span class="org-comment-delimiter">*/</span>
<span class="org-preprocessor">#define</span> <span class="org-variable-name">TCP_KEEPCNT</span> 0x102 <span class="org-comment-delimiter">/* </span><span class="org-comment">number of keepalives before close </span><span class="org-comment-delimiter">*/</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org43bfa71" class="outline-2">
<h2 id="org43bfa71">参考</h2>
<div class="outline-text-2" id="text-org43bfa71">
<ul class="org-ul">
<li>setsockopt(2)</li>
<li><a href="https://www.winehq.org/pipermail/wine-devel/2015-July/108583.html">ws2_32: socket keepalive for OSX</a></li>
<li><a href="https://github.com/redis/redis-rb/commit/58859678d781924f6899bf186d19a533b0b92817">Add support for specifying TCP keepalive configuration · redis/redis-rb@5885967</a></li>
</ul>
</div>
</div>Yoshinari Nomuraはじめに TCP keepalive を使ったプログラムを Ruby で書こうとしてはまったので,メモです.「パスワードは別途お送りします」を Mew でなんとかしたい2017-11-29T00:00:00+09:002017-11-29T00:00:00+09:00http://quickhack.net/nom/blog/mail-decrypter-for-mew<div id="outline-container-org3cc5562" class="outline-2">
<h2 id="org3cc5562">はじめに</h2>
<div class="outline-text-2" id="text-org3cc5562">
<p>
<a href="2017-11-06-password-is-in-another-mail.html">前回</a> に引き続き,「パスワードは別途お送りします」についてです.
今回は,Emacs 上のメーラ Mew で使えるツールの紹介です.
MH 形式 (1メール1ファイル) でメールを管理しているメーラであれば,
同じような方法が使えると思います.この場合,サーバが Gmail である必要はありません.
</p>
<p>
<!-- more -->
</p>
</div>
</div>
<div id="outline-container-org8de7946" class="outline-2">
<h2 id="org8de7946">使い方</h2>
<div class="outline-text-2" id="text-org8de7946">
<ol class="org-ol">
<li><a href="https://github.com/yoshinari-nomura/glima">glima</a> をインストールして,axman.el と axezip を使います.</li>
<li><p>
.emacs に以下を追加します:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">setq</span> axman-attachment-store-directory <span class="org-string">"~/Downloads"</span>)
(<span class="org-keyword">setq</span> load-path
(cons <span class="org-string">"~/path/to/this/file load-path"</span>))
(autoload 'axman-mew-decrypt-current-message-gmail <span class="org-string">"axman"</span>)
(autoload 'axman-mew-decrypt-current-message-local <span class="org-string">"axman"</span>)
</pre>
</div></li>
<li>Mew の summary buffer (たとえば %inbox) に
zip メールとパスワードメールが存在する状態で,
zip メールを表示しておきます.</li>
<li>M-x <code>axman-mew-decrypt-current-message-local</code></li>
<li>~/Downloads/ に暗号解読後の zip ファイルが置かれていると思います.</li>
</ol>
<p>
Gmail を Mew から読んでいる場合は,上記以外に
M-x <code>axman-mew-decrypt-current-message-gmail</code> で,
Gmail からzip メールとパスワードメールを探して処理できます.
両者が同一フォルダになくてもいいので,パスワードメールが同一フォルダに見当らない場合に便利だと思います.
</p>
</div>
</div>Yoshinari Nomuraはじめに 前回 に引き続き,「パスワードは別途お送りします」についてです. 今回は,Emacs 上のメーラ Mew で使えるツールの紹介です. MH 形式 (1メール1ファイル) でメールを管理しているメーラであれば, 同じような方法が使えると思います.この場合,サーバが Gmail である必要はありません.「パスワードは別途お送りします」をなんとかしたい2017-11-06T00:00:00+09:002017-11-06T00:00:00+09:00http://quickhack.net/nom/blog/password-is-in-another-mail<div id="outline-container-org38ee657" class="outline-2">
<h2 id="org38ee657">はじめに</h2>
<div class="outline-text-2" id="text-org38ee657">
<p>
メールの添付ファイルに暗号化 zip を送って,直後に別メールでパスワードだけ送ってくるアレ.
こんな話をよく聞きます:
</p>
<ul class="org-ul">
<li>パスワード入力するのが面倒</li>
<li>ゲートウェイでの「添付ファイルウィルススキャン」ができないので危険</li>
<li>セキュリティ向上の意味がほとんどないのでは?</li>
</ul>
<p>
タチの悪いことに,送信側は,そういう「メールソリューション」をお金をかけて導入していて,
ほぼ自動化してくれるので,送信者の意識なく,zip の中身が何であれすべて暗号化してしまいます.
受け取るほうは,たまったものではありません.
</p>
<p>
そこで,本日のお題は,「受信者側でパスワード別送zipメールに対抗する」です.
</p>
</div>
</div>
<div id="outline-container-org2109c01" class="outline-2">
<h2 id="org2109c01">glima</h2>
<div class="outline-text-2" id="text-org2109c01">
<p>
「パスワード別送zipメール」のパスワードを自動で解く方式を考えて実装しました.
</p>
<p>
<a href="https://github.com/yoshinari-nomura/glima">yoshinari-nomura/glima: Gmail CLI client.</a>
</p>
<p>
原理は簡単.いわゆる「ブルートフォース」をちょっと賢くやるだけです.
</p>
<ol class="org-ol">
<li>zip メールのパスワードが書いてそうなメールを探す.
以下の条件を満すメールを「パスワード候補メール」とします.
<ul class="org-ul">
<li>zipメールと From: が同じ</li>
<li>Date: が zipメールの前後 1日以内</li>
</ul></li>
<li>上で見付けた全ての「パスワード候補メール」から,ASCII-printable
が連続する文字列を抽出し,「パスワード候補文字列」とする.</li>
<li>全ての「パスワード候補文字列」を文字列の「エントロピーが高い順」にソートする.
「エントロピー」というのはここでは,「強いパスワードとされている度合」ぐらいの気持です.</li>
<li>ソート済みの「パスワード候補文字列」を順番に zip に適用してみる.</li>
</ol>
<p>
という方式です.これで,驚く程簡単にパスワードが解けます.
日本語のメールだと,大体,上位 3つぐらいの内にパスワードがヒットするので,解くのには 1秒もかかりません.
</p>
<p>
送る側が採用しているらしい,例の「メールソリューション」が
「強いパスワード」を付けてくれているおかげで,それを逆手に取ると,
高確率で真のパスワードが上位に来るというわけです.
</p>
</div>
</div>
<div id="outline-container-org7106406" class="outline-2">
<h2 id="org7106406">使い方その1</h2>
<div class="outline-text-2" id="text-org7106406">
<ol class="org-ol">
<li>Gmail の設定で,受信メールに "filename:zip -label:decrypted " でフィルタをかけて,
マッチしたメールに "queue" とでもラベルを付けておきます.</li>
<li><p>
以下のコマンドを実行します.
</p>
<pre class="example">
glima xzip "in:inbox label:queue" --del-src-labels=queue \
--del-dst-labels=queue \
--add-dst-labels=decrypted
</pre>
<p>
意味は:
</p>
<ol class="org-ol">
<li>inbox 中にある queue というラベルが付いているメールについて</li>
<li>元のメールの添付のzipをパスワードなしのものに置き換えたメールを作成し</li>
<li>queue ラベルを剥して,decrypted というラベルを付与し</li>
<li>Gmail に再びプッシュする</li>
</ol></li>
</ol>
<p>
ということをやります.
</p>
</div>
</div>
<div id="outline-container-org6d27fd7" class="outline-2">
<h2 id="org6d27fd7">使い方その2</h2>
<div class="outline-text-2" id="text-org6d27fd7">
<pre class="example">
glima dezip "15f4cf5c3376d343" ~/Downloads/
</pre>
<p>
意味は,Gmail の id 15f4cf5c3376d343 というメールの zipを解読して,パスワードなしの
zip ファイルを ~/Downloads/ に置く
という意味です.
</p>
</div>
</div>
<div id="outline-container-org8a62783" class="outline-2">
<h2 id="org8a62783">使い方その3 (2019-10-23 追記)</h2>
<div class="outline-text-2" id="text-org8a62783">
<p>
watch コマンドは,Gmail を IMAP IDLE で監視して,zip のパスワードをがんがん解いてくれます.
</p>
<ol class="org-ol">
<li>Gmail の設定で,受信メールに "filename:zip -label:decrypted " でフィルタをかけて,
マッチしたメールに "queue" とでもラベルを付けておきます.</li>
<li><p>
以下のコマンドで glima をバックグラウンド実行しておきます
</p>
<pre class="example">
glima watch queue decrypted >> $HOME/var/log/glima.log 2>&1 &
</pre></li>
</ol>
<p>
放置しておくだけで,zip の暗号を勝手にどんどん解いてくれます.
具体的には,
</p>
<ol class="org-ol">
<li>Gmail を監視して queue というラベルが付いているメールが届いたら</li>
<li>メール中のzipをパスワードなしのものに置き換えた別メールを作成し</li>
<li>別メールから queue ラベルを剥して decrypted というラベルを付与し Gmail に再びプッシュする</li>
<li>元メールからは queue ラベルを剥す</li>
</ol>
<p>
これでパスワード別送zipメールも恐くないですね.
</p>
</div>
</div>
<div id="outline-container-org405bba7" class="outline-2">
<h2 id="org405bba7">おわりに</h2>
<div class="outline-text-2" id="text-org405bba7">
<p>
glima という Gmail の CLI クライアントの機能として実装したので使ってみてください.
自身では,既に半年近く使ってますが,メールを受け取るのが嬉しくなりますよ :)
</p>
<p>
glima は,ラベルを一括で付け直したりなど,他にも便利なコマンドがあります.
</p>
<p>
次回は,Mew などの local フォルダを見るメーラから使う方法を紹介します.
</p>
<p>
<!-- more -->
</p>
</div>
</div>Yoshinari Nomuraはじめに メールの添付ファイルに暗号化 zip を送って,直後に別メールでパスワードだけ送ってくるアレ. こんな話をよく聞きます:Set your status in Slack with CLI2017-04-19T00:00:00+09:002017-04-19T00:00:00+09:00http://quickhack.net/nom/blog/set-your-status-in-slack-with-cli<div id="outline-container-org8bd27d3" class="outline-2">
<h2 id="org8bd27d3">Slack の新機能 Status</h2>
<div class="outline-text-2" id="text-org8bd27d3">
<p>
CLI から操作したいよね.ということで,簡単なシェルスクリプトを書いてみました.
<!-- more -->
</p>
</div>
</div>
<div id="outline-container-org2eb4e19" class="outline-2">
<h2 id="org2eb4e19">Shell script からステータスを簡単アップデート</h2>
<div class="outline-text-2" id="text-org2eb4e19">
<p>
ステータス機能の詳細は,以下の Slack の blog に書いてありました.
<a href="https://slackhq.com/set-your-status-in-slack-28a793914b98">Set your status in Slack - A new way to let your teammates know what you're up to</a>
</p>
<p>
でも GUI から変更するの面倒ですよね.末尾のようなスクリプトを ame という名前で
path の通ったところに置いて,
</p>
<pre class="example">
ame :office: "I'm at office!"
</pre>
<p>
などとすると,Slack の status が変わります.
</p>
<p>
Slack の API token は <code>~/.config/ame/config.sh</code> に置いておきます.
</p>
<div class="org-src-container">
<pre class="src src-shell-script"><span class="org-variable-name">DEFAULT_TEAM</span>=<span class="org-string">"yourteam"</span>
<span class="org-variable-name">TOKEN_YOURTEAM</span>=<span class="org-string">"xoxp-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxx"</span>
<span class="org-variable-name">TOKEN_ANOTHERTEAM</span>=<span class="org-string">"xoxp-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxx"</span>
</pre>
</div>
<p>
あなたの token は,<a href="https://api.slack.com/custom-integrations/legacy-tokens">Legacy tokens | Slack</a> から取れます.に書いてあります.
</p>
<p>
以下 ame スクリプトです.
gist も置きました: <a href="https://gist.github.com/yoshinari-nomura/37366e913db502672f5de70553c5cc8e">Set your status in Slack with CLI</a>
</p>
<div class="org-src-container">
<pre class="src src-shell-script"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span>
<span class="org-comment-delimiter">################################################################</span>
<span class="org-comment-delimiter">## </span><span class="org-comment">Usage</span>
<span class="org-function-name">usage</span>() {
<span class="org-builtin">echo</span> <span class="org-string">"ame [-c CONFIG_FILE] [-t TEAM] ICON TEXT"</span>
<span class="org-builtin">echo</span> <span class="org-string">" -c Set config file name."</span>
<span class="org-builtin">echo</span> <span class="org-string">" -t Set Slack team name."</span>
<span class="org-builtin">echo</span> <span class="org-string">"examples:"</span>
<span class="org-builtin">echo</span> <span class="org-string">" ame :office: \"I'm at office\""</span>
<span class="org-builtin">echo</span> <span class="org-string">" ame :house: \"I'm home\""</span>
} >&2
<span class="org-function-name">print_error</span>() {
printf <span class="org-string">"Error: $@\n"</span>
} >&2
<span class="org-comment-delimiter">################################################################</span>
<span class="org-comment-delimiter">## </span><span class="org-comment">Update Slack Status</span>
<span class="org-function-name">update_slack_status</span> () {
<span class="org-builtin">local</span> <span class="org-variable-name">token</span>=<span class="org-string">"$1"</span>
<span class="org-builtin">local</span> <span class="org-variable-name">emoji</span>=<span class="org-string">"$2"</span>
<span class="org-builtin">local</span> <span class="org-variable-name">stext</span>=<span class="org-string">"$3"</span>
<span class="org-builtin">local</span> <span class="org-variable-name">response</span>=$(curl -s -S -X POST <span class="org-sh-escaped-newline">\</span>
-d <span class="org-string">"token=$token"</span> <span class="org-sh-escaped-newline">\</span>
--data-urlencode <span class="org-string">"profile={\"status_text\": \"$stext\", \"status_emoji\": \"$emoji\"}"</span> <span class="org-sh-escaped-newline">\</span>
https://slack.com/api/users.profile.set <span class="org-sh-escaped-newline">\</span>
| sed -n <span class="org-string">'s/{"ok":false,"error":"\([^"]*\)".*/\1/p'</span>)
<span class="org-builtin">echo</span> <span class="org-string">"$response"</span> | tr <span class="org-string">'_'</span> <span class="org-string">' '</span>
}
<span class="org-comment-delimiter">################################################################</span>
<span class="org-comment-delimiter">## </span><span class="org-comment">Parse option</span>
<span class="org-variable-name">OPT_CONF</span>=<span class="org-string">"$HOME/.config/ame/config.sh"</span>
<span class="org-keyword">while </span><span class="org-builtin">getopts</span> <span class="org-string">"c:dt:"</span> flag
<span class="org-keyword">do</span>
<span class="org-keyword">case</span> $<span class="org-variable-name">flag</span><span class="org-keyword"> in</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">getopts sets '?' to flag on error.</span>
<span class="org-string">\?</span>|h) <span class="org-variable-name">OPT_ERROR</span>=1
;;
c) <span class="org-variable-name">OPT_CONF</span>=<span class="org-string">"$OPTARG"</span>
;;
d) <span class="org-variable-name">OPT_DEBUG</span>=<span class="org-string">"true"</span>
;;
t) <span class="org-variable-name">OPT_TEAM</span>=<span class="org-string">"$OPTARG"</span>
;;
<span class="org-keyword">esac</span>
<span class="org-keyword">done</span>
<span class="org-builtin">shift</span> $(( $<span class="org-variable-name">OPTIND</span> - 1 ))
<span class="org-comment-delimiter"># </span><span class="org-comment">unknown option check</span>
<span class="org-keyword">if</span> [ <span class="org-string">"$OPT_ERROR"</span> = 1 -o $<span class="org-variable-name">#</span> -ne 2 ]; <span class="org-keyword">then</span>
usage
<span class="org-keyword">exit</span> -1
<span class="org-keyword">fi</span>
<span class="org-comment-delimiter">################################################################</span>
<span class="org-comment-delimiter">## </span><span class="org-comment">Read Config</span>
<span class="org-comment-delimiter">#</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">config.sh Example:</span>
<span class="org-comment-delimiter">#</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">DEFAULT_TEAM="yourteam"</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">TOKEN_YOURTEAM="xoxp-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxx"</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">TOKEN_ANOTERTEAM="xoxp-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxx"</span>
<span class="org-comment-delimiter">#</span>
<span class="org-keyword">if</span> [ -f <span class="org-string">"$OPT_CONF"</span> ]; <span class="org-keyword">then</span>
<span class="org-builtin">source</span> <span class="org-string">"$OPT_CONF"</span>
<span class="org-keyword">else</span>
print_error <span class="org-string">"config $OPT_CONF not found."</span>
<span class="org-keyword">exit</span> -1
<span class="org-keyword">fi</span>
<span class="org-comment-delimiter">################################################################</span>
<span class="org-comment-delimiter">## </span><span class="org-comment">Set Slack API Token</span>
<span class="org-keyword">if</span> [ -z <span class="org-string">"$OPT_TEAM"</span> ]; <span class="org-keyword">then</span>
<span class="org-variable-name">OPT_TEAM</span>=<span class="org-string">"$DEFAULT_TEAM"</span>
<span class="org-keyword">fi</span>
<span class="org-variable-name">TOKEN_NAME</span>=TOKEN_$(<span class="org-builtin">echo</span> <span class="org-string">"$OPT_TEAM"</span> | tr a-z A-Z)
<span class="org-variable-name">TOKEN</span>=${<span class="org-variable-name">!</span>TOKEN_NAME}
<span class="org-keyword">if</span> [ -z <span class="org-string">"$TOKEN"</span> ]; <span class="org-keyword">then</span>
print_error <span class="org-string">"No API Token found for $OPT_TEAM in $OPT_CONF."</span>
<span class="org-keyword">exit</span> -1
<span class="org-keyword">fi</span>
<span class="org-comment-delimiter">################################################################</span>
<span class="org-comment-delimiter">## </span><span class="org-comment">Main</span>
<span class="org-keyword">if</span> [ -n <span class="org-string">"$OPT_DEBUG"</span> ]; <span class="org-keyword">then</span>
<span class="org-builtin">echo</span> <span class="org-string">"update_slack_status \"$TOKEN\" \"$1\" \"$2\""</span>
<span class="org-keyword">exit</span> 0
<span class="org-keyword">fi</span>
<span class="org-variable-name">error_message</span>=$(update_slack_status <span class="org-string">"$TOKEN"</span> <span class="org-string">"$1"</span> <span class="org-string">"$2"</span>)
<span class="org-keyword">if</span> [ -n <span class="org-string">"$error_message"</span> ]; <span class="org-keyword">then</span>
print_error <span class="org-string">"$error_message."</span>
<span class="org-keyword">exit</span> 1
<span class="org-keyword">fi</span>
<span class="org-keyword">exit</span> 0
</pre>
</div>
<p>
Skack は,お手軽にこういうことができるからいいですね.
僕は,センサから取得した自分の状態を Status に自動で反映させています.
</p>
<p>
Enjoy!
</p>
</div>
</div>Yoshinari NomuraSlack の新機能 Status CLI から操作したいよね.ということで,簡単なシェルスクリプトを書いてみました.Install Rust2017-04-13T00:00:00+09:002017-04-13T00:00:00+09:00http://quickhack.net/nom/blog/install-rust<div id="outline-container-org1565e08" class="outline-2">
<h2 id="org1565e08">Rust install が簡単になった</h2>
<div class="outline-text-2" id="text-org1565e08">
<p>
Rust を Sierra にインストールしてみました.
ちょっと見ない内に rustup というツールができてたみたいです.
</p>
<p>
<!-- more -->
</p>
<p>
homebrew とかでもインストールできるみたいですが,公式のおすすめ
curl …|sh でインストールしました.
</p>
<div class="org-src-container">
<pre class="src src-shell-script">% curl https://sh.rustup.rs -sSf | sh
info: downloading installer
Welcome to Rust!
This will download and install the official compiler for the Rust programming
language, and its package manager, Cargo.
It will add the cargo, rustc, rustup and other commands to Cargo<span class="org-string">'s bin</span>
<span class="org-string">directory, located at:</span>
<span class="org-string"> /Users/nom/.cargo/bin</span>
<span class="org-string">This path will then be added to your PATH environment variable by modifying the</span>
<span class="org-string">profile files located at:</span>
<span class="org-string"> /Users/nom/.profile</span>
<span class="org-string"> /Users/nom/.zprofile</span>
<span class="org-string">You can uninstall at any time with rustup self uninstall and these changes will</span>
<span class="org-string">be reverted.</span>
<span class="org-string">Current installation options:</span>
<span class="org-string"> default host triple: x86_64-apple-darwin</span>
<span class="org-string"> default toolchain: stable</span>
<span class="org-string"> modify PATH variable: yes</span>
<span class="org-string">1) Proceed with installation (default)</span>
<span class="org-string">2) Customize installation</span>
<span class="org-string">3) Cancel installation</span>
<span class="org-string">...</span>
<span class="org-string">Current installation options:</span>
<span class="org-string"> default host triple: x86_64-apple-darwin</span>
<span class="org-string"> default toolchain: stable</span>
<span class="org-string"> modify PATH variable: no</span>
</pre>
</div>
<p>
とやって, <code>.zshenv</code> に
</p>
<pre class="example">
source $HOME/.cargo/env
</pre>
<p>
を足しました.
</p>
<p>
参考: <a href="https://www.rust-lang.org/ja-JP/index.html">プログラミング言語 Rust</a>
</p>
</div>
</div>Yoshinari NomuraRust install が簡単になった Rust を Sierra にインストールしてみました. ちょっと見ない内に rustup というツールができてたみたいです.Who are you on the repository?2013-07-06T00:00:00+09:002013-07-06T00:00:00+09:00http://quickhack.net/nom/blog/who-are-you-on-the-repository<div id="outline-container-org61cbcaa" class="outline-2">
<h2 id="org61cbcaa">名を名乗れ!</h2>
<div class="outline-text-2" id="text-org61cbcaa">
<p>
Git の入門書には,大抵,まず自分の名前を設定しましょうと書いてあります.
たとえば,Pro Git <a href="http://git-scm.com/book/en/Getting-Started-First-Time-Git-Setup">Git - First-Time Git Setup</a> でも.
</p>
<div class="org-src-container">
<pre class="src src-shell-script">$ git config --global user.name <span class="org-string">"John Doe"</span>
$ git config --global user.email johndoe@example.com
</pre>
</div>
<p>
これ,設定してて困ったことありませんか? というのが今日の話です.
</p>
<p>
<!-- more -->
</p>
</div>
</div>
<div id="outline-container-org9366bb8" class="outline-2">
<h2 id="org9366bb8">よく忘れるリポジトリ毎の名前変更</h2>
<div class="outline-text-2" id="text-org9366bb8">
<p>
僕は,リポジトリ毎にメールアドレスを変えたいことがよくあります.そんなときは, <code>--global</code> を付けずに:
</p>
<div class="org-src-container">
<pre class="src src-shell-script">$ cd private-project
$ git config user.email private@example.com
</pre>
</div>
<p>
とすれば,そのリポジトリだけの local な設定として private@example.com が優先されます.ここまでは常識ですね.
</p>
<p>
ただ,これをよく忘れるんです.忘れると global な名前で commit message が残ってしまって,それに気付かずに push して面倒なことになります.
なので,僕は,global な user.email を設定していません.
</p>
<p>
では,global な設定をしないで,local な設定も忘れてしまうとどうなるでしょう.
望まないメールアドレスが外に出て行く心配はないのですが,
git が適当に自動で付けた名前と email アドレスで commit message が残ります.
これは,場合によっては,もっと恥ずかしいかもしれません.
</p>
<p>
なので,git は,push して恥ずかしい思いをする前に警告してくれます:
</p>
<div class="org-src-container">
<pre class="src src-shell-script">$ git commit -m <span class="org-string">'First import'</span>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:
git config --global user.name <span class="org-string">"Your Name"</span>
git config --global user.email you@example.com
After doing this, you may fix the identity used for this commit with:
git commit --amend --reset-author
</pre>
</div>
<p>
かしこいですね.
</p>
</div>
</div>
<div id="outline-container-org1a24a5e" class="outline-2">
<h2 id="org1a24a5e">でもね,できれば Commit する前に教えてよ…</h2>
<div class="outline-text-2" id="text-org1a24a5e">
<p>
でも,できれば commit する前に教えて欲しい.
pre-commit hook を設定すればいい気がしますが,そもそもこれを設定するのを忘れる…
そこで,zsh のプロンプトに出すことにしました.
</p>
<p>
<code>~/.zshrc</code> より抜粋:
</p>
<div class="org-src-container">
<pre class="src src-shell-script"><span class="org-comment-delimiter">##</span>
<span class="org-comment-delimiter">## </span><span class="org-comment">VCS and RVM info in prompt.</span>
<span class="org-comment-delimiter">##</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">http://qiita.com/items/8d5a627d773758dd8078</span>
+vi-check-git-repository-info() {
<span class="org-builtin">local</span> <span class="org-variable-name">email</span>=<span class="org-string">"$(git config --local --get user.email |cut -d. -f 1)"</span>
<span class="org-keyword">if</span> [[ <span class="org-string">"$1"</span> = 0 ]]; <span class="org-keyword">then</span>
<span class="org-keyword">if</span> [[ -n <span class="org-string">"$email"</span> ]]; <span class="org-keyword">then</span>
<span class="org-variable-name">hook_com</span>[misc]+=<span class="org-string">":$email"</span>
<span class="org-keyword">else</span>
<span class="org-variable-name">hook_com</span>[misc]=<span class="org-string">""</span>
<span class="org-keyword">fi</span>
<span class="org-keyword">fi</span>
<span class="org-keyword">if</span> [[ <span class="org-string">"$1"</span> = 1 ]]; <span class="org-keyword">then</span>
<span class="org-keyword">if</span> [[ -z <span class="org-string">"$email"</span> ]]; <span class="org-keyword">then</span>
<span class="org-variable-name">hook_com</span>[misc]+=<span class="org-string">"- WHO ARE YOU? - "</span>
<span class="org-keyword">else</span>
<span class="org-variable-name">hook_com</span>[misc]=<span class="org-string">""</span>
<span class="org-keyword">fi</span>
<span class="org-keyword">fi</span>
}
<span class="org-keyword">if</span> zsh-is-at-least 4.3.11 ; <span class="org-keyword">then</span>
<span class="org-builtin">autoload</span> -Uz vcs_info
zstyle <span class="org-string">':vcs_info:*'</span> formats <span class="org-string">'(%s%m)-[%b]'</span> <span class="org-string">'%m'</span>
zstyle <span class="org-string">':vcs_info:*'</span> actionformats <span class="org-string">'(%s)-[%b|%a]'</span>
zstyle <span class="org-string">':vcs_info:git+set-message:*'</span> hooks check-git-repository-info
precmd () {
<span class="org-variable-name">rvm_prompt</span>=<span class="org-sh-quoted-exec">`~/.rvm/bin/rvm-prompt`</span>
<span class="org-variable-name">psvar</span>=()
<span class="org-variable-name">LANG</span>=en_US.UTF-8 vcs_info
[[ -n <span class="org-string">"$vcs_info_msg_1_"</span> ]] && <span class="org-variable-name">psvar</span>[1]=<span class="org-string">"$vcs_info_msg_1_"</span>
[[ -n <span class="org-string">"$vcs_info_msg_0_"</span> ]] && <span class="org-variable-name">psvar</span>[2]=<span class="org-string">"$vcs_info_msg_0_"</span>
[[ -n <span class="org-string">"$rvm_prompt"</span> ]] && <span class="org-variable-name">psvar</span>[3]=<span class="org-string">"[$rvm_prompt]"</span>
}
<span class="org-variable-name">RPROMPT</span>=<span class="org-string">"%1(v|%F{red}%1v%f|)%2(v|%F{green}%2v%f|)%3(v|%F{yellow}%3v%f|)"</span>
<span class="org-keyword">fi</span>
</pre>
</div>
<p>
この設定で,email を設定していないと,<code>- WHO ARE YOU? -</code> と聞かれるようになります.
</p>
<figure>
<img src="dat/img/git-prompt-who-are-you.png" alt="git-prompt-who-are-you.png">
<figcaption><span class="figure-number">Figure 1: </span>ローカルな emai が設定されていないとき</figcaption>
</figure>
<figure>
<img src="dat/img/git-prompt-with-your-email.png" alt="git-prompt-with-your-email.png">
<figcaption><span class="figure-number">Figure 2: </span>ローカルな emai が設定されているとき</figcaption>
</figure>
<p>
となります.プロンプト右端は,rvm の情報なので,今回の話とは関係ありません.
</p>
<p>
あと,WHO ARE YOU と聞かれたときに簡単に返答できるようなエイリアスを作っています.
</p>
<p>
<code>~/.gitconfig</code>:
</p>
<pre class="example">
[alias]
email-github = config user.email github-username@example.com
email-work = config user.email work-username@example.com
</pre>
<p>
SPAM 対策で複数のメールアドレスを使い分けている人にも有効かもしれません.
</p>
</div>
</div>Yoshinari Nomura名を名乗れ! Git の入門書には,大抵,まず自分の名前を設定しましょうと書いてあります. たとえば,Pro Git Git - First-Time Git Setup でも.