2014-05-01 :-(
_ 読書メーター
2014年4月の読書メーター
読んだ本の数:5冊
読んだページ数:1161ページ
ナイス数:14ナイス
小学生からはじめるわくわくプログラミングの感想
Scratchでプログラムしましょうというもの。子供いませんが (´・ω・`) 私が子供ならインストールの段階で挫けそうなのでセットアップまでは大人の仕事か。アラン・ケイの言葉もあるのでどうぞ
読了日:4月27日 著者:阿部和広
魔法少女☆仮免許 (MF文庫J)の感想
H2SO4さんイラスト目当て / 魔法少女の仕組みはまだ明かされず。神獣が登場しまくり大げさな展開のようなのだが、うーん。水粂が可愛らしいイラストの割にヤンデレぶりが酷くて若干グロいのでちょっとなー / 周りくどい駆け引きは何かなーと思ったらそうか西尾維新か
読了日:4月16日 著者:冬木冬樹
部下を持ったら必ず読む 「任せ方」の教科書 「プレーイング・マネージャー」になってはいけない (ノンフィクション単行本)の感想
だいたいやってた / 出口治明ってデイリーポータルZやったひとか! @nifty:デイリーポータルZ:ハトが選んだ生命保険に入る http://portal.nifty.com/2009/07/24/a/
読了日:4月6日 著者:出口治明
艦隊これくしょん ‐艦これ‐ 一航戦、出ます! (角川スニーカー文庫)の感想
大破進撃 / 妖精が、人類は衰退したときの妖精に見えてきた / 天龍と龍田の武器は格闘戦で使うのかw / 「兵站が重要である」というゲームのテーマをよく表現しているし、それが第三章からの流れになっているし、提督側だけでなく深海棲艦側もそれは同じで提督と姫との対決としても描かれている / 他2種類の小説と比較して、提督の視点で戦術レベルを描いている。そのためゲームの世界も現状どうなっているのか想像しやすい
読了日:4月6日 著者:鷹見一幸
艦隊これくしょん -艦これ- 鶴翼の絆 (富士見ファンタジア文庫)の感想
我が鎮守府には瑞鶴も翔鶴も居ません。陽炎本の次に読んだ。艦娘とは何なのか、深海棲艦とは何なのか、作者ごとに解釈が異なっていて、その解釈ごとに世界が異なる。ガンダム小説を読むとジンクスやゲン担ぎを気にする描写がけっこうあるので、戦争のとき瑞鶴の「幸運」にすがりたいのは理解できる。
読了日:4月1日 著者:内田弘樹
読書メーター
_ 午後
1300 テストしTARI
_ 昨日買ったローラーを使ったら腹筋が筋肉痛になった
痛い
_ [ruby][mail][mime-types][gem]Unable to activate mail-2.5.4, because mime-types-2.2 conflicts with mime-types (~> 1.16) (Gem::LoadError)
環境
- Microsoft Windows 7 Proffesional
- ruby installer 2.0.0-p451
- mikel/mail - GitHub
現象
require 'mail' で死ぬ
m1.rb:5: warning: already initialized constant OpenSSL::SSL::VERIFY_PEER C:/Ruby200/lib/ruby/2.0.0/rubygems/specification.rb:2007:in `raise_if_conflicts': Unable to activate mail-2.5.4, because mime-types-2.2 conflicts with mime-types (~> 1.16) (Gem::LoadError) from C:/Ruby200/lib/ruby/2.0.0/rubygems/specification.rb:1176:in `activate' from C:/Ruby200/lib/ruby/2.0.0/rubygems.rb:186:in `rescue in try_activate' from C:/Ruby200/lib/ruby/2.0.0/rubygems.rb:183:in `try_activate' from C:/Ruby200/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:132:in `rescue in require' from C:/Ruby200/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:144:in `require' from m1.rb:10:in `<main>'
対策
gemspec を誤魔化せばイケる。ようだ。mjd
C:\Ruby200\lib\ruby\gems\2.0.0\specifications\mail-2.5.4.gemspec
これを
s.add_runtime_dependency(%q<mime-types>, ["~> 1.16"])
こうする
s.add_runtime_dependency(%q<mime-types>, [">= 0"])
2014-05-03 :-)
_ [艦これ]艦これ E-4【第2段階作戦】 中部太平洋海域
「哨戒線を押し上げるため、ピーコック島の攻略作戦を行う。進撃前路の対潜掃蕩を実施せよ!」
哨戒している潜水艦を撃破し、戦線を押し上げる。
キラ付け、ダメコン装備、前衛支援艦隊 が必要だった。装備が整っていればもっと楽に進撃できたんだろうけどあいにくいろいろ足りていない。
結局 主力艦隊はこう。( 【艦これ】E-4攻略 艦これ周回主義 支援艦隊 支援射撃の仕様と編成について改めて考える - 艦これ攻略日誌 ~艦ろぐ~ )
支援艦隊はこう。彗星一二型甲も流星改も持ってないので彗星を積んだ。
最初は何も考えずに出撃したところボス前で金剛が開幕爆撃により大破。旗艦大破により強制撤退。
しょうがないのでダメコンを全員に装備。応急修理要員です。応急修理女神は 1 つしか持ってない。
ダメコンは初めて使うんだけど、一度撃沈されるエフェクトがされるのね。心臓に悪いわ....
しかし、毎回ボスでダメコン発動してしまい( つまりボス前で大破し、進撃 ) あまりにも消費しすぎるので、ここで支援艦隊を使うことにした。決戦支援艦隊ではなく前衛支援艦隊。ボスは潜水艦しか居ないので支援艦隊の攻撃が当たらないし、問題はボスじゃなく、ボス前の被害を少なくすることである。
支援艦隊も初めて使った。エフェクトが熱い。
複数沈めてくれれば儲けもの。
大破が居なければいい。進撃
ルート固定なので毎回これ。
対潜要員が 5 人居るので負けはしない。
ボスドロップ。レアは長波くらいか。うーん
任務「第一次潜水艦派遣作戦」(遠征「潜水艦派遣作戦」) 完了
2014-05-04 :-)
_ [等々力渓谷][散歩]等々力渓谷とやらに行ってきた
テキトーに散歩しようと、何気なく大井町線 等々力駅で下車してみた。とりあえずテキトーに南側へ向かうかーと思い、駅からちょいと歩いたら何やらひとが出入りしている階段があった。等々力渓谷というらしい。せっかくだから降りてみた。
降りてみたら渓谷だった。等々力にこんなところがあったなんて知らなかった。道中には古墳があったりと完全に FF12 の世界なんですが 忙しい子がFF12をプレイ ~その56~ - YouTube
行き着いた先には神社があったり
等々力不動尊 だった。
シャクナゲだったかな
多摩川に沿ってテクテク歩いて帰るなどした。
_ [NetBSD][翻訳]hubertf's NetBSD blog - The NetBSD Foundation 2013 Financial Report The NetBSD Foundation 2013 会計報告
Following a recent internal meeting of the NetBSD project, the 2013 financial report is now available to the public. This gives an overview of NetBSD's financial situation, showing income from donations and merchandizing, and where money goes to: hardware, consulting for development, fees for banking, conferences and legal expenses.
先日内部的な NetBSD プロジェクト会議 { IRC とか? }にて、2013 年 会計報告 が公開された。これを読むと、NetBSD プロジェクトの財政状況が分かる。寄付やマーチャンダイジングによる収入や、支出の詳細: ハードウェア、開発のコンサルタント、銀行手数料、カンファレンスや訴訟費用といったことが分かる。
While NetBSD's finances are pretty safe and sound, more money is always welcome, to support developers working on features for money ("consulting") can do so in good manner.
NetBSD の財政はかなり安全だし健全だが、より多くの資金があるに越したことはない。資金をやりくりしている開発者( コンサルティング )の支援がうまくいく。
See for more information on how to support NetBSD!
詳細は NetBSD 支援方法を見てね。
_ [艦これ]艦これ E-5 【第2段階作戦】 北太平洋海域
「いよいよ北太平洋の離島、ピーコック島への攻略を実施する。索敵や対空見張りも厳とせよ!」
深海棲艦 離島基地を叩く。
2014春イベント最後の海域。
参考
E-5はヘビー級同士の殴り合いマップのため、戦艦、空母を使い、最大火力、最大レベルでファイ!してください。
こちらも持ちうる最大火力で挑む。
戦艦に昼戦連撃させるために、まず航空優勢をとる。んだが、烈風が足りないので開発。烈風以外にも彗星一二型甲ができてくれた。我が鎮守府初。
主力艦隊はこうした。46cm 砲は 2 つしか無い。もちろん全員キラ付け。コンディションは 70 くらいにした( 提督業も忙しい! - grabacr.nét 使ってます。コンディション数値が見れる )
決戦支援艦隊。
いざ出撃。
問題の 2 戦目。
出撃 1 回目は赤城さんが姫に殴られて大破。まだあと 3 戦目も控えていて、その後ボス戦なので、ダメコン発動させてもボス戦がツラいので撤退した。
再度準備して出撃 2 回目。相変わらず赤城さんが狙われるんですが今回は中破で耐えた。
姫は倒さない。とにかく姫から食らわなければいい。
3 戦目。単横で祈った。
そしてボス。
決戦支援艦隊!
ダメージは、うーん。
昼間で決着できないので夜戦に突入する。
霧島さんが連撃で旗艦を沈めてくれた。
満身創痍です。長門さんが無傷だった。さすがビッグ 7 は伊達じゃない。
A勝利ドロップは榛名
ひとまず 1 回撃破したけど、このあとどうするかのう。資材がなくなるまで挑戦してみるか。
2014-05-05 :-)
_ 午後
1300 デバッグしTARI
_ [艦これ]艦これ E-5
撃破 2 回目。
支援艦隊に三式弾を持たせる という話題があったので金剛さんに持たせてみた( 【艦これ】支援艦隊に三式弾を積むとE-5ボス艦隊に特効!?Twitterで話題に 【検証と考察】 : あ艦これ ~艦隊これくしょんまとめブログ~ )。
たこ焼きを沈めてくれた。まあオカルトの域を出ないみたいだけど、オカルトだろうがジンクスだろうがゲン担ぎだろうが何でもすがりたいのが艦これである。
今日は 4 回出撃してボス到達 1 回。その 1 回で長門さんが離島棲鬼を沈めてくれた。
同時進行の第二次潜水艦派遣作戦が完了した。
いわゆるスツーカ。
引き続き派遣しまくる。
烈風がもう 1 つ欲しいなあと開発していたら零式艦戦62型(爆戦) をゲット。
2014-05-06 :-)
_ 午後
1300 上野
_ [ぼたん][上野東照宮][ぼたん苑]上野東照宮 ぼたん苑 へ行ってきた
ぼたんを見てきた。
当初は 羊山公園の芝桜 ( 5/2 まで あの花 ラッピングバスがあったんだと。大型連休初日に行ったひとたちはそれ目当てだったのか ) へ行こうとしたんだが思い立ったのが日曜日であり 秩父鉄道 SLパレオエクスプレス の指定席は無く自由席も片道しか無いし、レッドアロー号の乗車券も無く池袋から西武秩父を往復する手段が無くなったので近場で過ごすことにした。やはり大型連休に出かけるものではない。
思っていたよりもけっこう数があった。途中から寒くなってきたので駆け足。
上野東照宮を眺めるなど。
その後は上野公園内のレストランでコーヒーを飲むなど。
_ [sysupgrade][NetBSD]sysupgrade
% uname -msr NetBSD 6.1.2 i386
% sysupgrade auto ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-6.1.4/i386
怒られた
sysupgrade: E: Failed to fetch ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-6.1.4/i386/binary/kernel/netbsd-MYKERNEL.gz
指定する。
% sysupgrade -o KERNEL=GENERIC auto ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-6.1.4/i386
以下略
% uname -msr NetBSD 6.1.4 i386
2014-05-07 :-(
_ 午後
1300 デバッグしTARI
_ [ruby][配布][ocra][exerb]ruby スクリプト配布方法
- Exerb ruby 1.9 未対応
- edvakf/RBat gem は回収してくれない
- ocra ruby 1.9 対応。gem 回収してくれる
ocra
例
# coding: utf-8 require 'rubygems' require 'mail' require 'pp' options = { :address => "smtp.example.jp", :port => 25, :domain => 'hogehoge.example.gr.jp', :user_name => 'hogehoge', :password => 'hogehoge', :authentication => 'plain', } Mail.defaults do delivery_method :smtp, options end mail = Mail.new mail.from = 'user1@example.jp' mail.to = 'user2@example.jp' mail.subject = '日本語タイトル' mail.charset ='iso-2022-jp' mail.add_content_transfer_encoding mail.body = '日本語本文' mail.deliver
インストール
gem install ocra
作る
>ocra send8.rb === Loading script to check dependencies === Detected gem mail-2.5.4 (loaded, files) === 137 files, 1526028 bytes === Detected gem mime-types-1.25.1 (loaded, files) === 32 files, 138537 bytes === Detected gem treetop-1.4.15 (loaded, files) === 13 files, 40028 bytes === Including 53 encoding support files (3349504 bytes, use --no-enc to exclude) DL is deprecated, please use Fiddle === Building send8.exe === Adding user-supplied source files === Adding ruby executable ruby.exe === Adding detected DLL C:/Ruby200-x64/bin/LIBEAY32.dll === Adding detected DLL C:/Ruby200-x64/bin/SSLEAY32.dll === Adding detected DLL C:/Ruby200-x64/bin/ZLIB1.dll === Adding detected DLL C:/Ruby200-x64/bin/libyaml-0-2.dll === Adding detected DLL C:/Ruby200-x64/bin/libffi-6.dll === Adding library files === Compressing 13587421 bytes === Finished building send8.exe (2918896 bytes)
あとは send8.exe を実行するだけ。
参考:
2014-05-10 :-)
_ [植松伸夫][中山博之][ファイナルファンタジー][ピアノオペラ]PIANO OPERA music from FINAL FANTASY
@よみうり大手町ホール
3/28 に出来たばかりらしい。大手の会社はこういうふうにお金を社会にたいして使い、社会貢献するんですなあ。まさにノブレス・オブリージュですな。
曲リストはファミ通かどこかに書かれるでしょう。
会場は 1 列目という席になったので植松伸夫を目前で眺めていた。お久しぶりです。丸刈りにしたから分からんだろうけど。
ファイナルファンタジーのピアノアレンジではあるんだけど、ピアノオペラは買ってない。昔からあるピアノアレンジのほうは持ってるので、ようするにその雰囲気です。
MC は台本どおりのようなんだけど、中山博之から植松伸夫への感謝の言葉が贈られるなど、ところどころサプライズがあったもよう。
おもにファイナルファンタジー 7, 8, 9 の曲を使っていて 8, 9 をプレイしていないおっさんにはあまりあまり。相変わらず客層が若いんだが 7, 8, 9 だからなのかなんなのか。
最後は FF6 「妖星乱舞」を演奏し、アンコールで FF5 「ビッグブリッヂの死闘」で終了した。妖星乱舞なんてピアノでよく演奏できるな。
2014-05-11 :-)
_ 午後
1400 アニメ消化
_ [横須賀][カレー]よこすかカレーフェスティバル2014
天気にも恵まれて、もうね。夏日です。日焼けして肌が痛い。日差しが夏だし。
先日の護衛艦カレーを食べられなかった[ 20140419#p04 ] のでリベンジとしてカレーを食べてきた。護衛艦カレーのときは客足が物凄かったが今回のはどうなんだろう護衛艦が来ないから少ないんだろか Yahoo! リアルタイム検索すると気合い入れて始発で行ったというひとも居るしなあとモンモンとしていたが結局開始時間に到着するようにした。アレ?少ないじゃん? と思ったんだが、カレーバイキングに長蛇の列ができていた。人気はこっちかー。
護衛艦カレーのときのカレーグランプリで 1 位になったカレーの列のほうが少ないし先日食べられなかったのでこっちに並んだ。うーん? 普通? 本来はりんごの擂り身が入ってるらしいんだが。
こちらカレーバイキング。列は 500 人くらい。30 分ほど並んでブースに入った。
他にもいくつか食べてきた。
2014-05-12 :-(
_ 午後
1300 デバッグしTARI
_ [hash][ハッシュ][ruby][プロパティ][アクセッサ]ハッシュのキーをプロパティのように扱う
よく attr_accessor してるんだけど数が増えると壊滅する。
# coding: utf-8 class PConfig attr_accessor :foo attr_accessor :bar attr_accessor :baz def initialize(config_path) config = eval(File.open(config_path).read) @foo = config[:foo] @bar = config[:bar] @baz = config[:baz] end end def main(argv) conf_path = argv[0] config = PConfig.new(conf_path) puts config.foo puts config.bar puts config.baz end main(ARGV)
こういうのを別途用意
# coding: utf-8 Config = { :foo => 'FOO', :bar => 'BAR', :baz => 'GAZ', }
実行
>ruby prop0.rb prop.conf FOO BAR GAZ
method_missing でイケるらしい。うーん。ハッシュキーをメソッド名(プロパティ)としてハッシュにアクセス(読出、そして代入も)するには - 別館 子子子子子子(ねこのここねこ)
prop.conf で symbol を使ってるので to_sym しておく。
# coding: utf-8 class PConfig def initialize(config_path) @config = eval(File.open(config_path).read) end def method_missing(name) return @config[name.to_sym] if @config.has_key?(name.to_sym) super.method_missing(name) end end def main(argv) conf_path = argv[0] config = PConfig.new(conf_path) puts config.foo puts config.bar puts config.baz end main(ARGV)
>ruby prop1.rb prop.conf FOO BAR GAZ
2014-05-13 :-(
_ 午後
1300 HDMIがどうのこうの
_ 右クリックで今日の日付のフォルダを作成する
やってるひとが居たんだが Windows - 右クリックメニューの新規作成から今日の日付フォルダーを一発で作れるようにする - Qiita
レジストリの Command のデータがよく分からん。
cmd /c md "%1..%%date:~-10,4%%%%date:~-5,2%%%%date:~-2,2%%"
たとえば
C:\home
というフォルダで右クリック - 新規作成 - フォルダー やると
C:\home\新規 フォルダー(yyyyMMdd形式).aaaafolder_yyyyMMdd..20140512
というフォルダが作成される。
%1 は cmd.exe への引数であり
C:\home\新規 フォルダー(yyyyMMdd形式).aaaafolder_yyyyMMdd
が渡されるんだが、じゃあ %1 を展開しようとして
cmd /c %~dp1
とやっても %~dp1 が "%~dp1" として処理されてしまう。%1 が展開されない。( basename と同じことをやろうとしている )
どうにも解決できないので以下のようにして exe を作成しておいてレジストリの Command からそれを呼び出して回避した。うーん。
C#
ToString のパス区切りはバックスラッシュじゃなくてスラッシュでもいいのかというかバックスラッシュが指定できない。( \\MM にすると \M と解釈されたうえに無視された )
class Program { static private String Today() { DateTime d = DateTime.Today; String today = d.ToString("yyyy/MM/dd"); return today; } static void Main(string[] args) { if (args.Length == 0) { return; } String basedir = Path.GetDirectoryName(args[0]); if (Directory.Exists(basedir) == false) { Console.WriteLine("ディレクトリを指定してね"); return; } String today = Today(); String path = Path.Combine(basedir, today); Console.WriteLine("create {0}", path); Directory.CreateDirectory(path); } }
Command のデータはこんな感じ。
cmd /c C:\mkdir-today.exe %1
実行すると
C:\home\2014\05\13
こういうふうに作成される。
2014-05-14 :-(
_ 午後
1300 HDMIがどうのこうの
_ 歓送迎会
異動
派遣って難しいよねー などといった感じで
派遣契約なんて長くて 3 年でありそんな短期で現場を離れる人間にたいしていろいろ業務を教育したところで 3 年すれば居なくなるので教育するだけの価値がない( カネと時間を投資しても割に合わない )うえに、派遣は切り捨て可能な戦力という扱いなわけだから属人性を高めてしまうわけにもいかない。
2014-05-15 :-(
_ 午後
1300 HDMIがどうのこうの
_ たまに秀丸の IME から Google IME が消える
なに?
_ フルスタックエンジニア
# coding: utf-8 class Stack def initialize(size) @size = size @stack ||= [] end def add(n) if @stack.length >= @size puts "stack full" return end @stack << n print end def print() p @stack end end def main(argv) stack = Stack.new(3) 0.upto(10) {|n| stack.add(n) } end main(ARGV)
% ruby stack0.rb [0] [0, 1] [0, 1, 2] stack full stack full stack full stack full stack full stack full stack full stack full
2014-05-17 :-)
_ 夜
1800 アニメ消化
_ [オクトーバーフェスト]日比谷オクトーバーフェスト2014
miwarin, yo_1, daresore
例年どおりに行ってきた。日比谷公園なんてオクトーバーフェストのときにしか来ない。
2 杯飲んだけど 2 杯目ですでに頭痛がしている。眠い。ビールはもはや 1 杯しか飲めないか。
バンドマン。ノリノリである。
よく見たらカメラ目線だった。ども
バンドのライブが終わり、1400 ころに離脱。
日比谷公園の店で披露宴らしきものが開催されていた。
_ [艦これ]艦これ 3-4 北方海域全域
北方海域艦隊決戦「北方海域奥地に敵艦隊の大規模泊地を発見!我が艦隊の総力を挙げてこれを撃滅せよ!」
先日 1 度出撃したものの初戦で大破撤退したので今回は 2 回目の出撃。
春イベント E-5 に挑戦したときと同じく今のところの我が鎮守府で最大火力、最大航空戦力の最強編成で挑む。とはいえ E-5 のときもそうだったんだけど戦艦のレベルを上げないといかんな。
先日は金剛 4 姉妹 + 赤城 + 加賀だったんだが今回は趣向を変更して長門型と金剛型にしてみた。長門 + 陸奥 + 金剛 + 比叡 + 赤城 + 加賀。全員キラ付け。装備はこう。クリア後ですが。
道中突破を考慮して彩雲を積まないで T 字不利にするという手もあるようなんだが、細けえこたぁいいんだよ。そんなことより航空優勢のほうが重要。道中もボスもひたすら単縦で殴りあう。殴り合い宇宙。
ボス前は戦艦 4 という最悪の編成だったが難なく撃破。
ボス。
夜戦で長門さんが殴ってくれた。
ボスS勝利。しかしこのときすでに保有艦娘が 100 人になっておった( 無課金です )。
_ ほげ
ほげほげ
2014-05-18 :-)
_ [C#][Lua][.NET]C# .NET から Lua
最近は NLua を使うらしい。
環境
- Microsoft Windows 7 64bit Professional
- Microsoft Visual Studio 2013 Express C#
- Proffesional .NET Framework 4.5
手順
ここのとおりに作業してみる C#にluaを組み込む方法 - Qiita
NLua は NuGet にもパッケージがあるんだが、そっちは動作未確認。
ダウンロード Win64 を取得
ファイルを展開
ファイルをテキトーなところに設置(プロジェクトから参照するとどうせ bin の下にコピーされるのでどこに設置してもよい)
C# プロジェクトを作成。ウィンドウフォームのアプリにする
プロジェクト - 参照設定 - 参照の追加 - 参照
さきほど設置した NLua のファイルのうち NLua.Win64\net45\NLua.dll を追加する。これだけでいい
test.lua をコピぺして bin/Debug に設置。
x = "lua:string test..."
フォームにボタンを設置
以下のコードを追加
using NLua; NLua.Lua lua = new NLua.Lua(); lua.DoFile("./test.lua"); var x = lua["x"]; MessageBox.Show(x.ToString()); lua.Close();
実行
エラー
型 'System.DllNotFoundException' のハンドルされていない例外が KeraLua.dll で発生しました 追加情報:DLL 'lua52' を読み込めません:指定されたモジュールが見つかりません。 (HRESULT からの例外:0x8007007E)
全然分からんのだが、結局以下のようにした。方法: 64 ビットの Visual C++ ツールセットをコマンド ラインから有効にする でいうところの x64 on x64 とする。
プロジェクト - プロパティ - ビルド - プラットフォームターゲット を x64 にする。
ビルドの構成マネージャー - アクティブソリューションプラットフォーム - 新規作成
新しいプラットフォームを入力または選択してください - x64 を入力
設定のコピー元 - Any CPU
プラットフォームターゲットとアクティブソリューションプラットフォームの違いが分からん。片方だけだとまだダメだった。
_ 買い物
iTunes Store
μ's や 765 プロダクションたちの歌は、世の中は愛に満ちあふれていて、希望は高く、最高にキラッキラに輝いているので聞いていてツラい。
- μ's - それは僕たちの奇跡 ラブライブ! 第 2 期 OP
- μ's - どんなときもずっと ラブライブ! 第 2 期 ED
- ClariS - STEP ニセコイ 第 2 期 OP
2014-05-19 :-(
2014-05-20 :-(
_ 午後
1300 デバッグしTARI
_ 夜
1700 残業アワー
2100 退勤 || ここんとこ無駄な時間が多いような || 以前は 17 時に退勤しないといけなかったから、どうすれば 17 時までに仕事を完了できるか、如何にして無駄をなくすか、ということに腐心していたんだが、最近の仕事場は【禁則事項です】なのでつい無制限に
2200 飯
_ [NetBSD][cat][コードリーディング]NetBSD /bin/cat を読む
src/bin/cat/cat.c
オプションなしで呼び出した場合を読む。
% cat file1 file2 file3
関数はこう呼ばれる
main raw_args raw_cat
main を読む。
(void)setlocale(LC_ALL, "");
マニュアルによると、"" を指定しているので環境変数 LC_ALL が使われる。
setlocale - NetBSD Manual Pages
Only three locales are defined by default, the empty string "" which denotes the native environment, and the "C" and "POSIX" locales, which denote the C language environment.
オプションを与えてないのでここは raw_args へ行く。
if (bflag || eflag || nflag || sflag || tflag || vflag) cook_args(argv); else raw_args(argv);
raw_args を読む。
全体が do while で囲まれている。
do { : } while (*argv);
argv には /bin/cat に渡された引数が入る。つまりファイル 1 つ以上である。ファイル 1 つ以上をすべて do while で処理する。
ファイルディスクリプタ fd に初期値設定。デフォルトでは標準入力。stdin はたぶん unistd.h で定義されてる。マニュアル stdin - NetBSD Manual Pages によると定数 STDIN_FILENO などらしいんだが。
fd = fileno(stdin); filename = "stdin";
条件分岐はここを通る。ようはファイルを open している。
else if ((fd = open(*argv, O_RDONLY, 0)) < 0) { skip: warn("%s", *argv); skipnomsg: rval = EXIT_FAILURE; ++argv; continue; }
open が返したファイルディスクリプタを raw_cat へ渡す。
raw_cat(fd);
raw_cat を読む。短いので関数を全部。ファイルから読んで標準出力 stdout へ書き出す。
void raw_cat(int rfd) { static char *buf; static char fb_buf[BUFSIZ]; static size_t bsize; ssize_t nr, nw, off; int wfd; wfd = fileno(stdout); // /bin/cat に渡されたファイル 1 つ以上を処理するので、buf は static であり最初だけ NULL チェックする if (buf == NULL) { struct stat sbuf; // ファイルサイズを取得する if (fstat(wfd, &sbuf) == 0 && sbuf.st_blksize > sizeof(fb_buf)) { bsize = sbuf.st_blksize; buf = malloc(bsize); } if (buf == NULL) { bsize = sizeof(fb_buf); buf = fb_buf; } } // 1 回の read で読みこみ完了するとは限らないのでループを回す while ((nr = read(rfd, buf, bsize)) > 0) // さらに write も 1 回で完了するとは限らないのでループする for (off = 0; nr; nr -= nw, off += nw) if ((nw = write(wfd, buf + off, (size_t)nr)) < 0) err(EXIT_FAILURE, "stdout"); if (nr < 0) { warn("%s", filename); rval = EXIT_FAILURE; } }
read はマニュアルにベストプラクティスが書いてある read - NetBSD Manual Pages 面倒くさい。
Error checks should explicitly test for -1. Code such as while ((nr = read(fd, buf, sizeof(buf))) > 0) is not maximally portable, as some platforms allow for nbytes to range between SSIZE_MAX and SIZE_MAX - 2, in which case the return value of an error-free read() may appear as a negative number distinct from -1. Proper loops should use while ((nr = read(fd, buf, sizeof(buf))) != -1 && nr != 0)
write(2) も当然ある write(2) - NetBSD Manual Pages
Error checks should explicitly test for -1. Code such as while ((nr = write(fd, buf, sizeof(buf))) > 0) is not maximally portable, as some platforms allow for nbytes to range between SSIZE_MAX and SIZE_MAX - 2, in which case the return value of an error-free write() may appear as a negative number distinct from -1. Proper loops should use while ((nr = write(fd, buf, sizeof(buf))) != -1 && nr != 0)
2014-05-21 :-)
_ 午前
1030 起床 && 1 回休み
1130 おひる。カレークリームスパゲティ && 今日は出かけようとしていたんだが雨なので腹いせにクリームソースを作った。最近は面倒くさいのであまり作らない。
_ 午後
1300 アニメ消化
_ [chmod][NetBSD][/bin/chmod][コードリーディング]NetBSD /bin/chmod を読む
処理の流れ。
main chmod または lchmod
chmod は libc の関数を使うのでぶっちゃけ main で完結してる。
main を読む。
最初に関数ポインタ変数を宣言している。これは後ほど使う。
int (*change_mode)(const char *, mode_t);
この 2 つ setlocale は /bin/cat でもやってたけどイディオムだろうか。
setprogname(argv[0]); (void)setlocale(LC_ALL, "");
オプション -h の処理
case 'h': /* * In System V the -h option causes chmod to * change the mode of the symbolic link. * 4.4BSD's symbolic links didn't have modes, * so it was an undocumented noop. In NetBSD * 1.3, lchmod(2) is introduced and this * option does real work. */ hflag = 1; break;
超訳「りりかる -h オプション 始まります」
System V の挙動にならったらしい。
-h が効くのがここ。main 関数chmod または lchmod を使う。change_mode は main 冒頭にあった関数ポインタ変数。
if (hflag) change_mode = lchmod; else change_mode = chmod;
ファイルの mode を変更する。
fts_open と fts_read はファイルシステムを渡り歩く fts_open - NetBSD Manual Pages
if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL) {
ここでファイルまたはディレクトリを渡り歩く。
for (rval = 0; (p = fts_read(ftsp)) != NULL;) { switch (p->fts_info) {
正味の mode 変更処理はここ。change_mode は先ほど chmod または lchmod が設定されている。どちらかを呼び出す。
if ((*change_mode)(p->fts_accpath, getmode(set, p->fts_statp->st_mode)) && !fflag) { warn("%s", p->fts_path); rval = 1; }
lchmod はここにある。結局 chmod を呼び出している。
src/tools/compat/lchmod.c
int lchmod(const char *path, mode_t mode) { struct stat psb; if (lstat(path, &psb) == -1) return -1; if (S_ISLNK(psb.st_mode)) { return 0; } return (chmod(path, mode)); }
chmod の定義がどうも chmod.S のようなんだが、chmod.S が見当たらない。
src/lib/libc/sys/Makefile.inc
# modules with default implementations on all architectures: ASM= access.S acct.S \ bind.S \ chdir.S chflags.S chmod.S chown.S chroot.S __clock_getres50.S \ __clock_gettime50.S \
2014-05-23 :-(
_ 午後
1300 デバッグしTARI
_ /etc/MAKEDEV
cd ~ /etc/MAKEDEV all
とやったけどどうも /dev にデバイスファイルが作成されないなー おかしいなー なんでだろうなーと思って中身を見てみた
usage() { cat 1>&2 << _USAGE_ Usage: ${0##*/} [-fMsu] [-m mknod] [-p pax] [-t mtree] special [...] Create listed special devices. Options: -f Force permissions to be updated on existing devices. -M Create memory file system. -m mknod Name of mknod(8) program. [\$TOOL_MKNOD or mknod] -p pax Name of pax(1) program. [\$TOOL_PAX or pax] -s Generate mtree(8) specfile instead of creating devices. -t mtree Name of mtree(8) program. [\$TOOL_MTREE or mtree] -u Don't re-create devices that already exist. _USAGE_ exit 1 }
あ
${0##*/}
嫌な予感が
oh
カレントディレクトリに作成されるのか。
ええとええと
-type t True if the file is of the specified type. Possible file types are as follows: b block special c character special d directory f regular file l symbolic link p FIFO s socket W whiteout w whiteout
まあとりあえずこれで
find ./ -type b | while read f; do rm -f $f; done
find ./ -type c | while read f; do rm -f $f; done
2014-05-24 :-)
_ 午前
1030 起床 && 部屋掃除
_ 生田緑地ばら苑
行ってきた
開園から 2 週間目だし、ブログを見たら「見頃を迎えています」とあったので( 小川宏氏のばら: 生田緑地ばら苑 公式ブログ ) 駐車場が超絶混雑してそうなのでリスクを回避するために自転車で行ってきた。片道 30 分くらい。
入場口についたら入場待ちの車が 20 台くらい待機していた。自転車で来たのは正解だった。(または電車でもどうぞ)
芝生に座ってヨタヨタする。ばら苑の入り口付近の売店で買ったものを食べるなど。
_ [NetBSD][/bin/date][コードリーディング]NetBSD /bin/date を読む
ソース src/bin/date/date.c
マニュアル date - NetBSD Manual Pages
日付を表示するときの流れ
main
日付を設定するときの流れ
main setthetime netsettime (?) settimeofday
main から読んでいく。
お馴染みの処理。
setprogname(argv[0]); (void)setlocale(LC_ALL, "");
ここでいろいろ分岐している。
// -r されてなかったらまず time で tval を初期化。 if (!rflag && time(&tval) == -1) err(EXIT_FAILURE, "time"); // date "+%Y/%m/%d%n %H:%M:%S" などと使われた場合 // format に argv ( +%Y/%m/%d%n %H:%M:%S ) が入る /* allow the operands in any order */ if (*argv && **argv == '+') { format = *argv; ++argv; } else // デフォルトがこのフォーマット format = "+%a %b %e %H:%M:%S %Z %Y"; // date 20140524 などと使われた場合は↑は else を通るので // ここで argv は 20140524 が入っている // それを使って setthetime を呼ぶ if (*argv) { setthetime(*argv); ++argv; } // これはなんだ.... if (*argv && **argv == '+') format = *argv; // 時間の文字列を格納するための配列。とりあえず 1024 としておく。 // あとで strftime したときのために malloc で作っておく。 if ((buf = malloc(bufsiz = 1024)) == NULL) goto bad; // localtime してる if ((tm = localtime(&tval)) == NULL) err(EXIT_FAILURE, "localtime %lld failed", (long long)tval); // strftime する // 0 (たぶんエラー) が返ってきたらとりあえず配列サイズを 2 倍にして再確保してリトライ while (strftime(buf, bufsiz, format, tm) == 0) if ((buf = realloc(buf, bufsiz <<= 1)) == NULL) goto bad; // 最後に印字して終了 (void)printf("%s\n", buf + 1); free(buf); return 0;
strftime は結局 非 0 なら正常終了、0 ならエラーと言ってるようだ。
strftime(3) - NetBSD Manual Pages
No more than maxsize characters will be placed into the array. If the total number of resulting characters, including the terminating null character, is not more than maxsize, strftime() returns the number of characters in the array, not counting the terminating null. Otherwise, zero is returned and the contents of the array are undefined.
ところで
Upon successful completion, time() returns the value of time. Otherwise a value of ((time_t) -1) is returned and the global variable errno is set to indicate the error.
おかしいときは -1 を返すよ。errno に値を設定するよ
ERRORS No errors are defined.
でもエラーが無い。
さて
日付を設定するときの処理 setthetime を読む。
for (t = p, dot = NULL; *t; ++t) { if (isdigit((unsigned char)*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); }
if (dot != NULL) { /* .ss */ len = strlen(dot); if (len != 3) badformat(); ++dot; lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badvalue("seconds"); } else { len = 0; lt->tm_sec = 0; }
ここでは
[[[[[[CC]yy]mm]dd]HH]MM[.SS]]
というフォーマットの最後の .SS が含まれているかどうかをチェックしている。↑の dot は .SS の . を意味する。
ここに出てきた ATOI2 は setthetime のすぐ上で定義されている。
#define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
ようするに文字列ポインタを 2 つ進めて、2 つ通り過ぎた 2 文字を 10 進法数値として扱う。
たとえば 20140524 という文字列の場合を考えてみる。
最初に呼び出すとき
ATOI2("20140524") ~~
"20" が取り出されて 20(10進法) となる。
次に呼び出すとき
ATOI2("20140524") ~~
"14" が取り出されて 14(10進法) となる。
以下同様。
switch ではこの仕組を利用して渡されたフォーマットを解析している。
yearset = 0; switch (strlen(p) - len) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; if (lt->tm_year < 0) badtime(); yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (yearset) { lt->tm_year += ATOI2(p); } else { yearset = ATOI2(p); if (yearset < 69) lt->tm_year = yearset + 2000 - TM_YEAR_BASE; else lt->tm_year = yearset + 1900 - TM_YEAR_BASE; } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if (lt->tm_mon > 12 || lt->tm_mon == 0) badvalue("month"); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); switch (lt->tm_mon) { case 0: case 2: case 4: case 6: case 7: case 9: case 11: if (lt->tm_mday > 31 || lt->tm_mday == 0) badvalue("day of month"); break; case 3: case 5: case 8: case 10: if (lt->tm_mday > 30 || lt->tm_mday == 0) badvalue("day of month"); break; case 1: if (lt->tm_mday > 29 || lt->tm_mday == 0 || (lt->tm_mday == 29 && !isleap(lt->tm_year + TM_YEAR_BASE))) badvalue("day of month"); break; default: badvalue("month"); break; } /* FALLTHROUGH */ case 4: /* hh */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badvalue("hour"); /* FALLTHROUGH */ case 2: /* mm */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badvalue("minute"); break; case 0: /* was just .sss */ if (len != 0) break; /* FALLTHROUGH */ default: badformat(); }
ここに出てくる TM_YEAR_BASE は src/lib/libc/time/tzfile.h で定義されてるものかな。以下の値となっている。2000 年問題ェ...
#define TM_YEAR_BASE 1900
FALLTHROUGH とあるように渡されたフォーマットを五月雨で処理していく。プログラミング言語 C には伝統として「switch case で break し忘れる」というバグがよく話題になるので、コメントとして書いておかないと break を意図して省いているのかどうか分からないのである。
実際に日付を設定している処理がここ。だと思う。
// or で繋がっているので nflag がどのような値であってもこの if は通る。 // つまり必ず netsettime が呼ばれる。はず /* set the time */ if (nflag || netsettime(new_time)) { logwtmp("|", "date", ""); if (aflag) { tv.tv_sec = new_time - tval; tv.tv_usec = 0; if (adjtime(&tv, NULL)) err(EXIT_FAILURE, "adjtime"); } else { tval = new_time; tv.tv_sec = tval; tv.tv_usec = 0; // ここで日付を設定 if (settimeofday(&tv, NULL)) err(EXIT_FAILURE, "settimeofday"); } logwtmp("{", "date", ""); }
nflag がなんのためにあるのか分からんのだが、netsettime を覗いてみる。
ソースは src/bin/date/netdate.c にある。
冒頭のコメント
/* * Set the date in the machines controlled by timedaemons by communicating the * new date to the local timedaemon. If the timedaemon is in the master state, * it performs the correction on all slaves. If it is in the slave state, it * notifies the master that a correction is needed. * Returns 0 on success. Returns > 0 on failure. */
結局 timed デーモンが起動していない場合はエラーになるけど、返り値は 0 超の値を返すらしい。
そして netsettime から返って ↑ の処理に戻る。ようだ。
netsettime の呼び出しが無駄なような...
2014-05-25 :-)
_ [NetBSD][npf][npf.conf]NetBSD npf.conf の例を読む
ref.
host-npf.conf
例 /usr/share/examples/npf/host-npf.conf
有線と無線のネットワーク
# $NetBSD: host-npf.conf,v 1.2.4.4 2012/12/15 23:31:07 riz Exp $ # # this is an example of NPF rules for a host (i.e., not routing) with # two network interfaces, wired and wifi # # it does both IPv4 and IPv6 and allows for DHCP in v4 and SLAAC in v6 # it also does IPSEC on the wifi # # 有線 NIC は wm0 $wired_if = "wm0" # IPv4 ネットワークアドレス $wired_v4 = { inet4(wm0) } # IPv6 ネットワークアドレス $wired_v6 = { inet6(wm0) } # 無線 NIC は iwn0 $wifi_if = "iwn0" # IPv4 ネットワークアドレス $wifi_v4 = { inet4(iwn0) } # IPv6 ネットワークアドレス $wifi_v6 = { inet6(iwn0) } # DHCP サーバーのアドレス $dhcpserver = { 198.51.100.1 } # ntp を使う $services_udp = { ntp } # sample mixed service # バックアップサーバー IPv4 $backupsrv_v4 = { 198.51.100.11 } # バックアップサーバー IPv6 $backupsrv_v6 = { 2001:0DB8:404::11 } # バックアップのポート amanda を使う $backup_port = { amanda } # npflog0 を使ってログする。という処理を定義。定義の名前は "log" procedure "log" { log: npflog0 } # グループを定義。名前: "wired" インターフェース: $wired_if group (name "wired", interface $wired_if) { # 以下のものを許可。final なので必ずこのルールを使う # 内向きパケット # IPv6 # ICMP pass in final family inet6 proto ipv6-icmp all # 以下のものを許可。final なので必ずこのルールを使う # 外向きパケット # IPv6 # ICMP pass out final family inet6 proto ipv6-icmp all # 以下のものを許可。final なので必ずこのルールを使う # 内向きパケット # IPv4 {注: inet じゃなくて inet4 じゃないのか?} # ICMP pass in final family inet proto icmp all # 以下のものを許可。final なので必ずこのルールを使う # 内向きパケット # IPv4 # TCP # 送信元: $dhcpserver のポート bootps # 送信先: $wired_v4 の ポート bootpc pass in final family inet proto tcp \ from $dhcpserver port bootps to $wired_v4 port bootpc # ↑を udp にも適用 pass in final family inet proto udp \ from $dhcpserver port bootps to $wired_v4 port bootpc # 以下のものを許可。final なので必ずこのルールを使う # 内向きパケット # IPv6 # TCP # 送信先: $wired_v6 の ssh pass in final family inet6 proto tcp to $wired_v6 port ssh # 以下のものを許可。final なので必ずこのルールを使う # 内向きパケット # IPv4 # TCP # 送信元: $backupsrv_v4 # 送信先: $wired_v4 ポート $backup_port # S/SA ( S と A (SYN と ACK) フラグだけに注目し、SYN フラグが "on" の場合に マッチ ) pass in final family inet proto tcp flags S/SA \ from $backupsrv_v4 to $wired_v4 port $backup_port # 以下のものを許可。final なので必ずこのルールを使う # 内向きパケット # IPv4 # UDP # 送信元: $backupsrv_v4 # 送信先: $wired_v4 ポート $backup_port pass in final family inet proto udp \ from $backupsrv_v4 to $wired_v4 port $backup_port # 以下のものを許可。final なので必ずこのルールを使う # 内向きパケット # IPv6 # TCP # S/SA # 送信元: $backupsrv_v6 # 送信先: $wired_v6 ポート $backup_port pass in final family inet6 proto tcp flags S/SA \ from $backupsrv_v6 to $wired_v6 port $backup_port # 以下のものを許可。final なので必ずこのルールを使う # 内向きパケット # IPv6 # UDP # 送信元: $backupsrv_v6 # 送信先: $wired_v6 ポート $backup_port pass in final family inet6 proto udp \ from $backupsrv_v6 to $wired_v6 port $backup_port # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 内向きパケット # IPv6 # UDP # 送信先: $wired_v6 ポート $services_udp pass stateful in final family inet6 proto udp to $wired_v6 \ port $services_udp # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 内向きパケット # IPv4 # UDP # 送信先: $wired_v6 ポート $services_udp {注: wired_v4 ではないのか?} pass stateful in final family inet proto udp to $wired_v6 \ port $services_udp # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 外向きパケット # IPv6 # TCP # フラグ S/SA # 送信元: $wired_v6 pass stateful out final family inet6 proto tcp flags S/SA \ from $wired_v6 # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 外向きパケット # IPv4 # TCP # フラグ S/SA # 送信元: $wired_v4 pass stateful out final family inet proto tcp flags S/SA \ from $wired_v4 # 以下のものを許可。final なので必ずこのルールを使う。 # 外向きパケット # IPv6 # TCP # 送信元: $wired_v6 pass out final family inet6 proto tcp from $wired_v6 # IPv4 も同様 pass out final family inet proto tcp from $wired_v4 # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 外向きパケット # IPv6 # 送信元: $wired_v6 pass stateful out final family inet6 from $wired_v6 # IPv4 も同様 pass stateful out final family inet from $wired_v4 } # 省略 group (name "wifi", interface $wifi_if) { : : : } # デフォルトグループ。default は必須 group (default) { # lo0 をすべて許可 pass final on lo0 all # ブロックしたパケットに "log" で処理 block all apply "log" }
soho_gw-npf.conf
例 /usr/share/examples/npf/soho_gw-npf.conf
NAT です
# $NetBSD: soho_gw-npf.conf,v 1.2.4.4 2012/12/15 23:31:07 riz Exp $ # # SOHO border # # This is a natting border gateway/webserver/mailserver/nameserver # IPv4 only # # 外部インターフェースは wm0 $ext_if = "wm0" # wm0 のアドレス $ext_v4 = inet4(wm0) # ifnet ってなんだ。inet4 がアドレスじゃないのか $ext_addrs = { ifnet(wm0) } # 内側インターフェースは wm1 $int_if = "wm1" # 1 という名前の静的テーブル。ハッシュ型。内容は hashtablefile から読む table <1> type hash file "/usr/share/examples/npf/hashtablefile" # 2 という名前の動的テーブル。ツリー型 table <2> type tree dynamic # TCP のサービス $services_tcp = { http, https, smtp, domain, 6000, 9022 } # UDP のサービス $services_udp = { domain, ntp, 6000 } $localnet = { 198.51.100.0/24 } # NAT 生成。$ext_if で 198.51.100.0/24 から $ext_v4 へ転送。 map $ext_if dynamic 198.51.100.0/24 -> $ext_v4 # NAT traffic arriving on port 9022 of the external interface address # to host 198.51.100.2 port 22 # NAT 生成。$ext_if で $ext_v4 port 9022 から 198.51.100.2 port 22 へ転送 map $ext_if dynamic 198.51.100.2 port 22 <- $ext_v4 port 9022 # "log" というプロシージャを定義 procedure "log" { log: npflog0 } # グループ 名前は "external" NIC は $ext_if group (name "external", interface $ext_if) { # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # すべてのパケット pass stateful out final all # 以下のものを破棄。final なので必ずこのルールを使う。 # グループ <1> からのすべてのパケット block in final from <1> # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 内向きパケット # IPv4 # TCP # 送信先 $ext_v4 port ssh # プロシージャ "log" を実行 pass stateful in final family inet proto tcp to $ext_v4 port ssh \ apply "log" # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 内向きパケット # TCP # 送信先 $ext_addrs port $services_tcp pass stateful in final proto tcp to $ext_addrs port $services_tcp # UDP も同様 pass stateful in final proto udp to $ext_addrs port $services_udp # Passive FTP # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 内向きパケット # TCP # 送信先 $ext_addrs port 49151-65535 pass stateful in final proto tcp to $ext_addrs port 49151-65535 # Traceroute # 以下のものを許可。final なので必ずこのルールを使う。stateful で状態監視 # 内向きパケット # UDP # 送信先 $ext_addrs port 33434-33600 pass stateful in final proto udp to $ext_addrs port 33434-33600 } # グループ 名前は "internal" NIC は $int_if group (name "internal", interface $int_if) { # すべてのパケットを破棄 block in all # 以下のものを許可。final なので必ずこのルールを使う。↑の block in all を上書き # 内向きパケット # 送信元 グループ <2> pass in final from <2> # 以下のものを許可。final なので必ずこのルールを使う。↑の block in all を上書き # 外向きパケット # あらゆるパケット pass out final all } # デフォルト # ようするにデフォルト破棄 group (default) { # lo0 をすべて許可。final なので必ずこのルールを使う pass final on lo0 all # すべてのパケットを破棄 block all }
2014-05-26 :-(
_ 午後
1300 タッチパネルはかく語りき
_ [NetBSD][/bin/echo][コードリーディング]NetBSD /bin/echo を読む
src/bin/echo/echo.c
こう使ったとする。
% echo foo bar baz foo bar baz
コード読む
/* ARGSUSED */ int main(int argc, char *argv[]) { int nflag; setprogname(argv[0]); (void)setlocale(LC_ALL, ""); // getopt 使うまでもないよ! /* This utility may NOT do getopt(3) option parsing. */ if (*++argv && !strcmp(*argv, "-n")) { ++argv; nflag = 1; } else nflag = 0; // argv は以下のとおり // argv[1] : foo // argv[2] : bar // argv[3] : baz while (*argv) { (void)printf("%s", *argv); if (*++argv) (void)putchar(' '); } // 最後に改行を印字 if (nflag == 0) (void)putchar('\n'); fflush(stdout); // fflush の動作を保証するため? if (ferror(stdout)) exit(1); exit(0); /* NOTREACHED */ }
-n オプションの意味
-n Do not print the trailing newline character.
_ [NetBSD][/bin/hostname][コードリーディング]NetBSD /bin/hostname を読む
ソース src/bin/hostname/hostname.c
マニュアル hostname - NetBSD Manual Pages
使用例
% hostname sakura.area51.gr.jp
% hostname -s sakura
コード読む。
main で完結する。
冒頭の変数
char *p, hostname[MAXHOSTNAMELEN + 1];
MAXHOSTNAMELEN は src/sys/sys/param.h に定義されてる。
/* * Machine-independent constants (some used in following include files). * Redefined constants are from POSIX 1003.1 limits file. * * MAXCOMLEN should be >= sizeof(ac_comm) (see <acct.h>) * MAXHOSTNAMELEN should be >= (_POSIX_HOST_NAME_MAX + 1) (see <limits.h>) * MAXLOGNAME should be >= UT_NAMESIZE (see <utmp.h>) */ #include <sys/syslimits.h> #define MAXCOMLEN 16 /* max command name remembered */ #define MAXINTERP PATH_MAX /* max interpreter file name length */ /* DEPRECATED: use LOGIN_NAME_MAX instead. */ #define MAXLOGNAME (LOGIN_NAME_MAX - 1) /* max login name length */ #define NCARGS ARG_MAX /* max bytes for an exec function */ #define NGROUPS NGROUPS_MAX /* max number groups */ #define NOGROUP 65535 /* marker for empty group set member */ #define MAXHOSTNAMELEN 256 /* max hostname size */
おもな処理。ようするに sethostname または gethostname を呼ぶ。
if (*argv) { // ホスト名が指定されている場合はホスト名を設定 if (sethostname(*argv, strlen(*argv))) err(1, "sethostname"); } else { // 指定されてなければ gethostname でホスト名を取得 if (gethostname(hostname, sizeof(hostname))) err(1, "gethostname"); // ヌル文字を入れる hostname[sizeof(hostname) - 1] = '\0'; // -s で呼び出された場合 最初の . を探す。 // そこにヌル文字を突っ込むことで強制的に文字列を終了する。つまりドメイン名を削除 if (sflag && (p = strchr(hostname, '.'))) *p = '\0'; (void)printf("%s\n", hostname); }
hostname は以下のファイルに定義されている。libc です。
src/lib/libc/gen/gethostname.c
int gethostname(name, namelen) char *name; size_t namelen; { int mib[2]; size_t size; _DIAGASSERT(name != NULL); mib[0] = CTL_KERN; mib[1] = KERN_HOSTNAME; size = namelen; // 第 3 引数が非 NULL なので情報を取得 if (sysctl(mib, 2, name, &size, NULL, 0) == -1) return (-1); return (0); }
sethostname も同じところにある。
src/lib/libc/gen/sethostname.c
int sethostname(name, namelen) const char *name; size_t namelen; { int mib[2]; _DIAGASSERT(name != NULL); mib[0] = CTL_KERN; mib[1] = KERN_HOSTNAME; // 第 3 引数が NULL なので情報を設定 if (sysctl(mib, 2, NULL, NULL, name, namelen) == -1) return (-1); return (0); }
双方とも sysctl を呼んでいる。
sysctl のマニュアル。
- sysctl(3) - NetBSD Manual Pages プログラマ向け
- sysctl(7) - NetBSD Manual Pages システム管理者向け
sysctl(3) より。sysctl の第 3 引数が NULL ならば設定。そうでなければ情報を取得。
The information is copied into the buffer specified by oldp. The size of the buffer is given by the location specified by oldlenp before the call, and that location gives the amount of data copied after a successful call. If the amount of data available is greater than the size of the buffer supplied, the call supplies as much data as fits in the buffer provided and returns with the error code ENOMEM. If the old value is not desired, oldp and oldlenp should be set to NULL.
sysctl(7) より。CTL_KERN と KERN_HOSTNAME を指定すると kern.hostname が使われる。
Name Constant Next level names Description kern CTL_KERN <sys/sysctl.h> High kernel limits
kern.hostname (KERN_HOSTNAME) Get or set the hostname(1).
2014-05-27 :-(
_ 午後
1300 検討
_ [コードリーディング][NetBSD][/bin/domainname][domainname][getdomainname][setdomainname]NetBSD /bin/domainname を読む
ソース src/bin/domainname/domainname.c
マニュアル domainname - NetBSD Manual Pages
読む。
if (*argv) { if (setdomainname(*argv, strlen(*argv))) err(1, "setdomainname"); } else { if (getdomainname(domainname, sizeof(domainname))) err(1, "getdomainname"); (void)printf("%s\n", domainname); }
とはいえこれも hostname と同じ。getdomainname または setdomainname を呼び出す。
マニュアル getdomainname - NetBSD Manual Pages
ソース src/lib/libc/gen/setdomainname.c
int setdomainname(name, namelen) const char *name; size_t namelen; { int mib[2]; _DIAGASSERT(name != NULL); mib[0] = CTL_KERN; mib[1] = KERN_DOMAINNAME; if (sysctl(mib, 2, NULL, NULL, name, namelen) == -1) return (-1); return (0); }
ソース src/lib/libc/gen/getdomainname.c
int getdomainname(name, namelen) char *name; size_t namelen; { int mib[2]; size_t size; int olderrno; _DIAGASSERT(name != NULL); mib[0] = CTL_KERN; mib[1] = KERN_DOMAINNAME; size = namelen; olderrno = errno; if (sysctl(mib, 2, name, &size, NULL, 0) == -1) { if (errno == ENOMEM) { errno = olderrno; return (0); } return (-1); } return (0); }
sysctl を呼び出す
- sysctl(3) - NetBSD Manual Pages プログラマ向け
- sysctl(7) - NetBSD Manual Pages システム管理者向け
CTL_KERN と KERN_DOMAINNAME はこれ
kern.domainname (KERN_DOMAINNAME) Get or set the YP domain name.
_ [NetBSD][/bin/kill][kill][コードリーディング]NetBSD /bin/kill を読む
ソース src/bin/kill/kill.c
マニュアル kill - NetBSD Manual Pages
使用例
kill 12345 kill -9 12345 kill -HUP 12345 kill -SIGHUP 12345
よむ。
numsig にデフォルトのシグナル番号を設定。デフォルトでは SIGTERM
numsig = SIGTERM;
↑のように呼び出した場合。つまり -l も -s もしない場合はここを通る。
} else if (**argv == '-') { char *sn = *argv + 1; // kill -HUP 12345 などの場合 if (isalpha((unsigned char)*sn)) { // -HUP や -SIGHUP を 9 へ変換して numsig へ格納 if ((numsig = signame_to_signum(sn)) < 0) nosig(sn); // kill -9 12345 などの場合 } else if (isdigit((unsigned char)*sn)) { // 数値へ変換して numsig へ格納 numsig = strtoimax(sn, &ep, 10); 以下略
シグナル名からシグナル番号へ変換する処理を見る。
static int signame_to_signum(char *sig) { int n; // SIGHUP などが与えられた場合は HUP とする if (strncasecmp(sig, "sig", 3) == 0) sig += 3; // sys_signame を線形探索してシグナル名を検索 // シグナル名が格納されているインデックスがそのままシグナル番号となる。 for (n = 1; n < NSIG; n++) { if (!strcasecmp(sys_signame[n], sig)) return (n); } return (-1); }
strncasecmp は大文字小文字を区別しないで比較 strcasecmp - NetBSD Manual Pages
sys_signame は以下で定義されている。
lib/libc/compat/gen/compat_signame.c
const char *const sys_signame[] = { "Signal 0", /* 0 */ "HUP", /* 1 SIGHUP */ "INT", /* 2 SIGINT */ "QUIT", /* 3 SIGQUIT */ "ILL", /* 4 SIGILL */ "TRAP", /* 5 SIGTRAP */ "ABRT", /* 6 SIGABRT */ "EMT", /* 7 SIGEMT */ "FPE", /* 8 SIGFPE */ "KILL", /* 9 SIGKILL */ "BUS", /* 10 SIGBUS */ "SEGV", /* 11 SIGSEGV */ "SYS", /* 12 SIGSYS */ "PIPE", /* 13 SIGPIPE */ "ALRM", /* 14 SIGALRM */ "TERM", /* 15 SIGTERM */ "URG", /* 16 SIGURG */ "STOP", /* 17 SIGSTOP */ "TSTP", /* 18 SIGTSTP */ "CONT", /* 19 SIGCONT */ "CHLD", /* 20 SIGCHLD */ "TTIN", /* 21 SIGTTIN */ "TTOU", /* 22 SIGTTOU */ "IO", /* 23 SIGIO */ "XCPU", /* 24 SIGXCPU */ "XFSZ", /* 25 SIGXFSZ */ "VTALRM", /* 26 SIGVTALRM */ "PROF", /* 27 SIGPROF */ "WINCH", /* 28 SIGWINCH */ "INFO", /* 29 SIGINFO */ "USR1", /* 30 SIGUSR1 */ "USR2", /* 31 SIGUSR2 */ };
続き。
プロセス番号を得る。文字列から数値へ変換
pid = strtoimax(*argv, &ep, 10);
ここに来るまでで得たシグナル番号とプロセス番号を用いて kill(2) を呼ぶ。kill(2) - NetBSD Manual Pages
if (kill((pid_t) pid, (int) numsig) == -1) {
2014-05-29 :-(
_ 午後
1300 lint祭り
_ [NetBSD][/bin/ln][ln][コードリーディング]NetBSD /bin/ln を読む
ソース src/bin/ln/ln.c
使用例
ln -s src dst
流れ
main linkit link または symlink
コード読む
main の外にグローバル変数が宣言されている。関数ポインタへの変数
static int (*linkf)(const char *, const char *);
main() はこう。
-s した場合は symlink を設定し、そうでなければ link を使う。
if (sflag) { linkf = symlink; linkch = '-'; } else { linkf = link; linkch = '='; }
dst がディレクトリでなければここを通っておしまい。
switch(argc) { case 0: usage(); /* NOTREACHED */ case 1: /* ln target */ exit(linkit(argv[0], ".", 1)); /* NOTREACHED */ // ln -s src dst だとここを通る case 2: /* ln target source */ exit(linkit(argv[0], argv[1], 0)); /* NOTREACHED */ }
linkit() を読む
lstat してファイル存在有無確認してるらしい lstat - NetBSD Manual Pages lstat の戻り値は以下のとおり。正常なら 0 、そうでないなら -1 が返る。
RETURN VALUES The stat(), lstat(), fstat(), and fstatat() functions return the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error.
というわけで
// 正常ならば exists は 1 になる exists = !lstat(source, &sb); // ln -f src dst と呼ばれたら以下が通る // 一度 unlink つまり削除しているらしい。えー /* * If the file exists, then unlink it forcibly if -f was specified * and interactively if -i was specified. */ if (fflag && exists) { if (unlink(source)) { warn("%s", source); return (1); }
最後に linkf で link または symlink を呼び出す。
/* Attempt the link. */ if ((*linkf)(target, source)) { warn("%s", source); return (1); }
2014-05-30 :-(
_ 午後
1300 lint祭り
_ 夜
1700 退勤
1800 人事評価の基準について上司たちと認識合わせ @コメダ珈琲店 下丸子店 自社の基準はあるけどアレって自社作業が前提だからいまの派遣先には適合できないよねだからオレはカクカクシカジカと考えてるから部下をこう氷菓したんだけど課長以上はどういう基準なの?っていう
1900 上司たちと連れ立って飯@まるりゅう 下丸子店
_ ,
Warning Warning 君の朝だよ♪
2014-05-31 :-)
_ 午後
1500 撤退
_ [NHK技研公開][NHK]NHK技研公開2014
今年も行ってきた。
ガイドツアーに申し込み、開始時間までヨタヨタする。
とりあえず昼飯。今年も食堂を利用する。
これがどーもくん弁当。ひき肉が入っているので食べませんが。
昼飯を終えてもまだガイドツアーまで時間があったので少し回ってみた。
8K 撮影テレビの変遷というのが展示してあったので背面を眺めてきた。
このコネクタすげえな。自衛隊の機器とかでしか見たこと無いんだけど。
時間になったのでガイドツアーを回ってきた。。
ガイドツアーは約 1 時間ほど。フロアー 1 階はやはり 8K を押してるなー。2020 年の東京オリンピック( not AKIRA )までに 8K を間に合わせるらしい。ということはその前までに 8K を表示できるテレビが発売されるはずだし、表示だけでなく撮影する機器も 8K のビデオカメラが発売されるはずだし。
8K の低スペックなら対応してる機器はあるけどフルスペックはまだ全然普及してないどころか民生品は無いとかなんとか言ってたような。
フルスペック:
- 画素数 7680×4320
- ビット深度 12
- レームレート 120 Hz
120 Hz のテレビってなんだよ
60 Hz と 120 Hz で比較している展示があったので聞いてみた。
オレ「 120 Hz を再生するテレビなんてあるんですか」
説明員「業務用です」
オレ「ですよねー。でもお高いんでしょう」
説明員「知らね。分かんね」
なお 60 Hz と 120 Hz との比較は、120 Hz が気持ち悪いくらいにヌルヌル動いていた。
ガイドツアーが解散になり、地下 1 F で テレビ視聴時の興味内容推定を利用した番組ナビゲーション の説明員の話を聞いて、振り返ったら @studio5 が居た。テキトーにヨタヨタした。
1億3300万画素イメージセンサー とか桁が違っており意味がわからない。
インテグラル立体テレビ は数年前から見かけるんだけど、実用化は 2030 年をメドにしているんだそうな。先が長いな....
ポスター展示 で「脳活動分析による番組視聴中の心理状態推定技術」の話を聞くなどしていた。ここんとこ NHK 技研公開で機械学習のネタをよく見かけるん。番組についてアンケートとるという手法だと番組全体のフィードバックしか得られない。番組中の各場面ごとに視聴者が感じることは異なるはずだ、きっと脳波に影響があるんじゃないか( 仮説 )。では計測してみよう。感情はたくさんあるので、まずは試しに「笑い」の感情に注目してみよう。お笑い番組を fMRI で脳の状態を解析し、番組の場面と脳波に相関があるのか、無いのか( 検証 )。「笑い」の瞬間の脳波との関連ははっきりしなかったけど、笑うタイミングの前兆がありそうだということがわかった( 結果 )。当然ひとによって笑いのタイミングは異なるんだが、サンプル 10 人やっておおむね同じような傾向があった。本来やろうとしていたこと「笑いのタイミング」での脳波との関連は、脳波だけでなく、表情なども計測することで妥当性を検証できるだろう( 考察 )。
といったことを言っていた。
感情は笑いだけでなく例えば Plutchikの感情の輪 といった感情モデルというのがある。NHK 技研ではないが、感情モデルと辞書を用いて、テキストから感情を分析するという研究もある。NHK 技研の説明員はこれには触れていなかったが、当然ながらこういった多様な感情分析にも着手するであろう。たぶん
どーもくんを買ってきた。
_ みわ [あーあーあー]
_ Fryght [航空戦艦を使えば制空権争いが少し楽になるかも。]
_ みわ [航空戦艦も徹甲弾を積めるんだよねえ。しかしレベル40とか50くらいなので育てるか。。。]