let's reading oss's source
TRANSCRIPT
Let’s reading OSS’s sourceOpen Source Software
真面目な話はできません。
自己紹介
今 利仁 / Toshihito Kon@Tkon_sec
なぜか”てまー”と呼ばれているLinuxクソザコマン
どんなひと
どんなひと
- ブロック崩し課題で音ゲー作る
どんなひと
- ブロック崩し課題で音ゲー作る
- バブみの宣教師みたいな扱いを受けるようになる
どんなひと
- ブロック崩し課題で音ゲー作る
- バブみの宣教師みたいな扱いを受けるようになる
- バイトの面接で”バブみ”について説明させられる
どんなひと
- ブロック崩し課題で音ゲー作る
- バブみの宣教師みたいな扱いを受けるようになる
- バイトの面接で”バブみ”について説明させられる
- 講義をサボってLinuxConJapanへ行く
どんなひと
- ブロック崩し課題で音ゲー作る
- バブみの宣教師みたいな扱いを受けるようになる
- バイトの面接で”バブみ”について説明させられる
- 講義をサボってLinuxConJapanへ行く
- LPI-Japanの人と仲良くなってRPiセミナー開く- 半額提供のためにRPi電子工作
どんなひと
- ブロック崩し課題で音ゲー作る
- バブみの宣教師みたいな扱いを受けるようになる
- バイトの面接で”バブみ”について説明させられる
- 講義をサボってLinuxConJapanへ行く
- LPI-Japanの人と仲良くなってRPiセミナー開く- 半額提供のためにRPi電子工作
- 最近コンピューターアーキテクチャの勉強を始めた
どんなひと
- ブロック崩し課題で音ゲー作る
- バブみの宣教師みたいな扱いを受けるようになる
- バイトの面接で”バブみ”について説明させられる
- 講義をサボってLinuxConJapanへ行く
- LPI-Japanの人と仲良くなってRPiセミナー開く- 半額提供のためにRPi電子工作
- 最近コンピューターアーキテクチャの勉強を始めた
- 和服好き
どんなひと
どんなひと
普通の人です。
What OSS
What OSS
OSS : Open Source Software
ソースコードが無償で公開され、誰でも改良・再配布が許可されているソフトウェア
What OSS
OSS : Open Source Software
タダで使える
せっかくソースも公開されてるなら読んでみよう
kernel.org
kernel.org
Linux kernel Download
← kernel directory
大量のC言語ソースファイル
main関数が見つからない
main関数が見つからない
→ 初心者にとっての死
main関数が見つからない
→ 初心者にとっての死
main関数が見つからない
→ 初心者にとっての死
ちゃんとみつけました。kernelディレクトリじゃなかったよ!
600万行のLinuxKernelは流石に手強い
600万行のLinuxKernelは流石に手強い
手すらつけれてないとか言うな
もっと小さいものはないのか
もっと小さいものはないのか
→ あります。 当たり前だよなぁ
本題
のソースを読んでみよう。
feh (ふぇふ?)
軽量なイメージビューア。各形式の画像の表示やデスクトップ背景の
設定までこなす高機能さも兼ね備える。
シンプルでとても使い勝手が良い
https://feh.finalrewind.org
https://feh.finalrewind.org
← source download
← src directory
← main.c
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
src/main.c
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
main関数短い!!
src/main.c
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
main関数短い!!
src/main.c
コメント少ないけど関数の意味がわかる!某講義の2~3行に1コメントとか頭おかしいでしょ
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
3部構成初期化
モード設定
メインループ
src/main.c
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
src/main.c
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings();}
たぶんこれがウィンドウの初期設定だろう
init_x_and_imlib()が書いてありそうなファイルを探す
init_x_and_imlib()が書いてありそうなファイルを探す
imlib.cそれっぽいぞ
void init_x_and_imlib(void){ disp = XOpenDisplay(NULL); if (!disp) eprintf("Can't open X display. It *is* running, yeah?"); vis = DefaultVisual(disp, DefaultScreen(disp)); depth = DefaultDepth(disp, DefaultScreen(disp)); cm = DefaultColormap(disp, DefaultScreen(disp)); root = RootWindow(disp, DefaultScreen(disp)); scr = ScreenOfDisplay(disp, DefaultScreen(disp)); xid_context = XUniqueContext();
#ifdef HAVE_LIBXINERAMA init_xinerama();#endif /* HAVE_LIBXINERAMA */
imlib_context_set_display(disp); imlib_context_set_visual(vis); imlib_context_set_colormap(cm); imlib_context_set_color_modifier(NULL); imlib_context_set_progress_function(NULL); imlib_context_set_operation(IMLIB_OP_COPY); wmDeleteWindow = XInternAtom(disp, "WM_DELETE_WINDOW", False);
/* Initialise random numbers */ srand(getpid() * time(NULL) % ((unsigned int) -1));
return;}
src/imlib.c
void init_x_and_imlib(void){ disp = XOpenDisplay(NULL); if (!disp) eprintf("Can't open X display. It *is* running, yeah?"); vis = DefaultVisual(disp, DefaultScreen(disp)); depth = DefaultDepth(disp, DefaultScreen(disp)); cm = DefaultColormap(disp, DefaultScreen(disp)); root = RootWindow(disp, DefaultScreen(disp)); scr = ScreenOfDisplay(disp, DefaultScreen(disp)); xid_context = XUniqueContext();
#ifdef HAVE_LIBXINERAMA init_xinerama();#endif /* HAVE_LIBXINERAMA */
imlib_context_set_display(disp); imlib_context_set_visual(vis); imlib_context_set_colormap(cm); imlib_context_set_color_modifier(NULL); imlib_context_set_progress_function(NULL); imlib_context_set_operation(IMLIB_OP_COPY); wmDeleteWindow = XInternAtom(disp, "WM_DELETE_WINDOW", False);
/* Initialise random numbers */ srand(getpid() * time(NULL) % ((unsigned int) -1));
return;}
src/imlib.c
X周りのセットアップ
imlibのセットアップ
X(X window system)は知ってるけどimlibってなんぞ?
Imlib2 … 画像処理ライブラリ。ファイルの読み込み、出力、X windowへの描画等の基本的な機能が揃っている。
ほへぇ(知見を得たときの感嘆詞)
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
初期化
モード設定
メインループ
src/main.c
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
src/main.c
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode();
...
“opt”大活躍
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
src/main.c
init_parse_options(argc, argv);
引数を元にoptをセット
src/option.h
extern fehoptions opt;
fehoptions型
src/structs.h
typedef struct __fehoptions fehoptions;
fehoptions型 → 実態はstruct __fehoptions 構造体
struct __fehoptions { unsigned char multiwindow; unsigned char montage; unsigned char collage; unsigned char index; unsigned char thumbs; unsigned char slideshow; unsigned char recursive; unsigned char output; unsigned char verbose; unsigned char display; unsigned char bg; unsigned char alpha; unsigned char alpha_level; unsigned char aspect; unsigned char stretch; unsigned char keep_http; unsigned char borderless; unsigned char randomize; unsigned char jump_on_resort; unsigned char full_screen; unsigned char draw_filename;#ifdef HAVE_LIBEXIF unsigned char draw_exif;#endif unsigned char list; unsigned char quiet; unsigned char preload; unsigned char loadables; unsigned char unloadables; unsigned char reverse; unsigned char no_menus; unsigned char scale_down; unsigned char bgmode; unsigned char xinerama; unsigned char screen_clip; unsigned char hide_pointer; unsigned char draw_actions; unsigned char draw_info; unsigned char cache_thumbnails; unsigned char cycle_once; unsigned char hold_actions[10]; unsigned char text_bg; unsigned char image_bg; unsigned char no_fehbg; unsigned char keep_zoom_vp; unsigned char insecure_ssl;
char *output_file; char *output_dir; char *bg_file; char *font; char *title_font; char *title; char *thumb_title; char *actions[10]; char *action_titles[10]; char *fontpath; char *filelistfile; char *menu_font; char *customlist; char *menu_bg; char *caption_path; char *start_list_at; char *info_cmd; char *index_info;
int force_aliasing; int thumb_w; int thumb_h; int limit_w; int limit_h; unsigned int thumb_redraw; double reload; int sort; int debug; int geom_flags; int geom_x; int geom_y; unsigned int geom_w; unsigned int geom_h; int default_zoom; int zoom_mode; unsigned char adjust_reload; int xinerama_index;
/* signed in case someone wants to invert scrolling real quick */ int scroll_step;
unsigned int min_width, min_height, max_width, max_height;
unsigned char mode; unsigned char paused;
double slideshow_delay;
signed short magick_timeout;
Imlib_Font menu_fn;};
src/optioins.h struct __fehoption
struct __fehoptions { unsigned char multiwindow; unsigned char montage; unsigned char collage; unsigned char index; unsigned char thumbs; unsigned char slideshow; unsigned char recursive; unsigned char output; unsigned char verbose; unsigned char display; unsigned char bg; unsigned char alpha; unsigned char alpha_level; unsigned char aspect; unsigned char stretch; unsigned char keep_http; unsigned char borderless; unsigned char randomize; unsigned char jump_on_resort; unsigned char full_screen; unsigned char draw_filename;#ifdef HAVE_LIBEXIF unsigned char draw_exif;#endif unsigned char list; unsigned char quiet; unsigned char preload; unsigned char loadables; unsigned char unloadables; unsigned char reverse; unsigned char no_menus; unsigned char scale_down; unsigned char bgmode; unsigned char xinerama; unsigned char screen_clip; unsigned char hide_pointer; unsigned char draw_actions; unsigned char draw_info; unsigned char cache_thumbnails; unsigned char cycle_once; unsigned char hold_actions[10]; unsigned char text_bg; unsigned char image_bg; unsigned char no_fehbg; unsigned char keep_zoom_vp; unsigned char insecure_ssl;
char *output_file; char *output_dir; char *bg_file; char *font; char *title_font; char *title; char *thumb_title; char *actions[10]; char *action_titles[10]; char *fontpath; char *filelistfile; char *menu_font; char *customlist; char *menu_bg; char *caption_path; char *start_list_at; char *info_cmd; char *index_info;
int force_aliasing; int thumb_w; int thumb_h; int limit_w; int limit_h; unsigned int thumb_redraw; double reload; int sort; int debug; int geom_flags; int geom_x; int geom_y; unsigned int geom_w; unsigned int geom_h; int default_zoom; int zoom_mode; unsigned char adjust_reload; int xinerama_index;
/* signed in case someone wants to invert scrolling real quick */ int scroll_step;
unsigned int min_width, min_height, max_width, max_height;
unsigned char mode; unsigned char paused;
double slideshow_delay;
signed short magick_timeout;
Imlib_Font menu_fn;};
src/optioins.h struct __fehoption
main関数より長い
オプションの設定項目の列挙
src/optioins.c void init_parse_options(int argc char **argv)
void init_parse_options(int argc, char **argv){ /* TODO: sort these to match declaration of __fehoptions */
/* For setting the command hint on X windows */ cmdargc = argc; cmdargv = argv;
/* Set default options */ memset(&opt, 0, sizeof(fehoptions)); opt.display = 1; opt.aspect = 1; opt.slideshow_delay = 0.0; opt.magick_timeout = -1; opt.thumb_w = 60; opt.thumb_h = 60; opt.thumb_redraw = 10; opt.scroll_step = 20; opt.menu_font = estrdup(DEFAULT_MENU_FONT); opt.font = NULL; opt.menu_bg = estrdup(PREFIX "/share/feh/images/menubg_default.png"); opt.max_height = opt.max_width = UINT_MAX;
opt.start_list_at = NULL; opt.jump_on_resort = 1;
opt.screen_clip = 1;#ifdef HAVE_LIBXINERAMA /* if we're using xinerama, then enable it by default */ opt.xinerama = 1; opt.xinerama_index = -1;#endif /* HAVE_LIBXINERAMA */
feh_getopt_theme(argc, argv);
D(("About to check for theme configuration\n")); feh_check_theme_options(argv);
D(("About to parse commandline options\n")); /* Parse the cmdline args */ feh_parse_option_array(argc, argv, 1);
/* If we have a filelist to read, do it now */ if (opt.filelistfile) { /* joining two reverse-sorted lists in this manner works nicely for us here, as files specified on the commandline end up at the *end* of the combined filelist, in the specified order. */ D(("About to load filelist from file\n")); filelist = gib_list_cat(filelist, feh_read_filelist(opt.filelistfile)); }
D(("Options parsed\n"));
filelist_len = gib_list_length(filelist); if (!filelist_len) show_mini_usage();
check_options();
feh_prepare_filelist(); return;}
src/optioins.c void init_parse_options(int argc char **argv)
optにデフォルト値セット
コマンドライン引数をfeh_getopt_theme(argc, argv);でパースしてopt設定
void init_parse_options(int argc, char **argv){ /* TODO: sort these to match declaration of __fehoptions */
/* For setting the command hint on X windows */ cmdargc = argc; cmdargv = argv;
/* Set default options */ memset(&opt, 0, sizeof(fehoptions)); opt.display = 1; opt.aspect = 1; opt.slideshow_delay = 0.0; opt.magick_timeout = -1; opt.thumb_w = 60; opt.thumb_h = 60; opt.thumb_redraw = 10; opt.scroll_step = 20; opt.menu_font = estrdup(DEFAULT_MENU_FONT); opt.font = NULL; opt.menu_bg = estrdup(PREFIX "/share/feh/images/menubg_default.png"); opt.max_height = opt.max_width = UINT_MAX;
opt.start_list_at = NULL; opt.jump_on_resort = 1;
opt.screen_clip = 1;#ifdef HAVE_LIBXINERAMA /* if we're using xinerama, then enable it by default */ opt.xinerama = 1; opt.xinerama_index = -1;#endif /* HAVE_LIBXINERAMA */
feh_getopt_theme(argc, argv);
D(("About to check for theme configuration\n")); feh_check_theme_options(argv);
D(("About to parse commandline options\n")); /* Parse the cmdline args */ feh_parse_option_array(argc, argv, 1);
/* If we have a filelist to read, do it now */ if (opt.filelistfile) { /* joining two reverse-sorted lists in this manner works nicely for us here, as files specified on the commandline end up at the *end* of the combined filelist, in the specified order. */ D(("About to load filelist from file\n")); filelist = gib_list_cat(filelist, feh_read_filelist(opt.filelistfile)); }
D(("Options parsed\n"));
filelist_len = gib_list_length(filelist); if (!filelist_len) show_mini_usage();
check_options();
feh_prepare_filelist(); return;}
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
optの値を見てモード設定するだけ。
src/main.c
int main(int argc, char **argv){ atexit(feh_clean_exit);
setup_signal_handlers(); init_parse_options(argc, argv);
init_imlib_fonts();
if (opt.display) { init_x_and_imlib(); init_keyevents(); init_buttonbindings(); }
feh_event_init();
if (opt.index) init_index_mode(); else if (opt.collage) init_collage_mode(); else if (opt.multiwindow) init_multiwindow_mode(); else if (opt.list || opt.customlist) init_list_mode(); else if (opt.loadables) init_loadables_mode(); else if (opt.unloadables) init_unloadables_mode(); else if (opt.thumbs) init_thumbnail_mode(); else if (opt.bgmode) { feh_wm_set_bg_filelist(opt.bgmode); exit(0); } else { /* Slideshow mode is the default. Because it's spiffy */ opt.slideshow = 1; init_slideshow_mode(); }
/* main event loop */ while (feh_main_iteration(1));
return(0);}
メインループ
src/main.c
眠いのでここまで。
今後の可能性
Imlib2を使ってなにか組んでみる?
せっかくimlib.cにまとめてあるのでこれを利用してみる?
それともfeh自体を改造してオレオレアプリにする?
理想(背景透明化)
まとめ
OSSのソースコードは(一部を除き)難しくない。
中身がどうなってるのかわからないものほど読むのが楽しい。
サノバウィッチ / ゆずソフト
真面目な宣伝
札幌で “NoCTF(Not only CTF)”を開催します。
日程:12/11(予定)概要:セキュリティ分野で有名なCTF(Captuer The Flag)を、
もっと幅広い分野でゆるくやろう、という試み。 早い話がITクイズ大会。
詳細は追ってTwitter等で告知します。
おしまい