Sieve は、メールフィルタリングのための言語です。
メールサーバー上にフィルタリングルールを定義したファイルを予め置いておき、サーバー上でメールをフィルタリングすることでクライアントの環境に依存しない点が売りです。
今回は、Sieve の Dovecot 向け実装であるPIGENHOLEをインストールしてみました。
[A] インストール
インストール自体は、メールサーバーにて
cd /usr/ports/mail/dovecot2-pgenhole/
make config-recursive
make
make install clean
で終了。
PIGENHOLE のSieve は、Dovecotのプラグインとして提供されているのでこのプラグインを有効にします。この設定は、受信したメールのローカルユーザーへの配信をLDA/LMTPのどちらで行なっているかに依存するので予め確認しておく必要があります。デフォルトでは、LDAを用いているようです。
以下LDAの場合の例 /usr/local/etc/dovecot/conf.d/90-plugin.conf に以下を追加
protocol lda{
mail_plugins = sieve
}
[B} フィルタリングルール作成
フィルタリングルールは、ルールを適用したいユーザーのホームディレクトリに「.dovecot.sieve」を作成してこのファイルの中に記述していきます。
以下はそのサンプル。
require ["fileinto"];
if address :is "from" "foo@example.jp" {
fileinto "INBOX.spam";
}
foo@example.jp からのメールをspamフォルダーに振り分けます。そしてこの.dovecot.sieveを以下コマンドでコンパイルして「~/.dovecot.svbin」として出力します。
sievec ~/.dovecot.sieve ~/.dovecot.svbin
これで次回メール受信時から作成したルールが適用されます。ルールが適用されないようであれば~/.dovecot.sieve.log にログが出力されるので参考にします。
今回は、ここまで
今後は、スクリプトファイルのUNICODE対応やThunderbirdのsieveのスクリプトを編集できるAdd On等を試してみたい。。。
2013年6月28日金曜日
2013年6月27日木曜日
[FreeBSD] dovecot2 のインストール
要点のみをかいつまんで。。。
1) コンパイル と インストール
2) 設定ファイル例をコピー
/usr/local/share/doc/dovecot 以下の dovecot.conf と conf.d ディレクトリを /usr/lolcal/etc/dovecot にコピー
3) 認証プロトコルの設定
今回は、テスト用途なんで plain 認証でいきます。 先ほどコピーしたconf.d ディレクトリ中の
10-ssl.conf 中の
#ssl =yes
を
ssl = no
に変更し、同ディレクトリ中の 10-auth.conf の
#disable_plaintext_auth = yes
を
disable_plaintext_auth = no
とし、明示的にsslを使わない様に変更。これに気づかずかなり時間を食った
4) デーモンプロセス 始動
/usr/local/etc/rc.d/postfix
起動時に自動でデーモンを起動した場合は、
/etc/rc.conf に以下を追加
dovecot_enable="YES"
1) コンパイル と インストール
2) 設定ファイル例をコピー
/usr/local/share/doc/dovecot 以下の dovecot.conf と conf.d ディレクトリを /usr/lolcal/etc/dovecot にコピー
3) 認証プロトコルの設定
今回は、テスト用途なんで plain 認証でいきます。 先ほどコピーしたconf.d ディレクトリ中の
10-ssl.conf 中の
#ssl =yes
を
ssl = no
に変更し、同ディレクトリ中の 10-auth.conf の
#disable_plaintext_auth = yes
を
disable_plaintext_auth = no
とし、明示的にsslを使わない様に変更。これに気づかずかなり時間を食った
4) デーモンプロセス 始動
/usr/local/etc/rc.d/postfix
起動時に自動でデーモンを起動した場合は、
/etc/rc.conf に以下を追加
dovecot_enable="YES"
2013年6月26日水曜日
2013年6月10日月曜日
[FreeBSD] Windows の共有ディレクトリをマウント
CentOS に続き FreeBSDでも
mount_smb -I host-addr //host-name/ /mnt/path-to-mount-point
ex) mount_smb -I 192.168.100.2 //win-pc/ /mnt/windir
2013年5月15日水曜日
[Code reading] time command
[Motivation]
FORTRANで記述されコンパイラで自動並列化した数値解析のプログラムの実行時間を下記環境でtimeコマンドを使って測定したら下記の様な結果になった。
-実行環境-
OS: Cent OS
CPU: Intel Xeon Processor L5640 x 2
-並列数-
OMP_NUM_THREAD=12
-time コマンド結果-
real 84m23.521s
user 1010m2.767s
sys 0m7.199s
[reasoning]
user時間は、各コアのuser時間の合計となるためスレッド並列化して実行したコマンドでは、real時間よりも長くなることがある?
適当なミラーサイトからソースを取ってくる。
後、linuxカーネル(2.6.34)のソースも取ってくる。
まずは、タイムコマンドのmain関数
-time.c: main
632 main (argc, argv)
633 int argc;
634 char **argv;
635 {
636 const char **command_line;
637 RESUSE res;
…
640 run_command (command_line, &res);
641 summarize (outfp, output_format, command_line, &res);
run_commandという関数を見てみる
-time.c: run_command
597 static void
598 run_command (cmd, resp)
599 char *const *cmd;
600 RESUSE *resp;
601 {
…
605 resuse_start (resp);
…
614 execvp (cmd[0], cmd);
…
623 if (resuse_end (pid, resp) == 0)
timeコマンドで指定したコマンドをexecvp関数で実行している.
execvp関数の前後で呼んでいるresuseで始まる関数を次に見てみる
-resuse.c: resuse_start
46 void
47 resuse_start (resp) //resuseは、resource use startの略と思われる。
48 RESUSE *resp;
49 {
50 #if HAVE_WAIT3
51 gettimeofday (&resp->start, (struct timezone *) 0);
52 #else
53 long value;
54 struct tms tms;
55
56 value = times (&tms); // man によると返り値は過去のある時点からのtick
57 resp->start.tv_sec = value / HZ; // HZ は、CPUクロックか? 確証は得られてない
58 resp->start.tv_usec = value % HZ * (1000000 / HZ);
59 #endif
60 }
現在のクロックカウント(と言っていいのか?)をHZで割って時刻をresp->start.tvに保持する
-resuse.c: resuse_end
117 resp->elapsed.tv_sec -= resp->start.tv_sec; // real time (sec)?
124 resp->elapsed.tv_usec -= resp->start.tv_usec; // real time (micro sec)?
コマンド実行後に省略したが同様にCPU時刻を取得して実行前の時刻を引いている。=> 正味実行にかかった時間(real time)を算出。
struct tmsとは何か?
struct tms -> linux/times.h
6 struct tms {
7 __kernel_clock_t tms_utime; // user time
8 __kernel_clock_t tms_stime; // system time
9 __kernel_clock_t tms_cutime; // child process user time
10 __kernel_clock_t tms_cstime; // child process system time
11 };
__kernel_clock_t -> linux/types.h
79 typedef __kernel_clock_t clock_t;
-time.c : summarize
320 static void
321 summarize (fp, fmt, command, resp)
322 FILE *fp;
323 const char *fmt;
324 const char **command;
325 RESUSE *resp;
326 {
-kernel/sys.c 912 void do_sys_times(struct tms *tms)
921 tms->tms_utime = cputime_to_clock_t(tgutime);
922 tms->tms_stime = cputime_to_clock_t(tgstime);
923 tms->tms_cutime = cputime_to_clock_t(cutime);
924 tms->tms_cstime = cputime_to_clock_t(cstime);
thread_group_timesとは
kernel/sched.c
3398 void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
3399 {
3400 struct task_cputime cputime;
3401
3402 thread_group_cputime(p, &cputime);
3403
3404 *ut = cputime.utime;
3405 *st = cputime.stime;
3406 }
kernel/posix_cpu_timers.c
234 void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
235 {
236 struct sighand_struct *sighand;
237 struct signal_struct *sig;
238 struct task_struct *t;
239
240 *times = INIT_CPUTIME;
241
242 rcu_read_lock();
243 sighand = rcu_dereference(tsk->sighand);
244 if (!sighand)
245 goto out;
246
247 sig = tsk->signal;
248
249 t = tsk;
250 do {
251 times->utime = cputime_add(times->utime, t->utime);
252 times->stime = cputime_add(times->stime, t->stime);
253 times->sum_exec_runtime += t->se.sum_exec_runtime;
254
255 t = next_thread(t);
256 } while (t != tsk);
257
258 times->utime = cputime_add(times->utime, sig->utime);
259 times->stime = cputime_add(times->stime, sig->stime);
260 times->sum_exec_runtime += sig->sum_sched_runtime;
261 out:
262 rcu_read_unlock();
263 }
include/asm-generic/cputime.h
12 #define cputime_add(__a, __b) ((__a) + (__b))
next_thread(t);とは
include/linux/sched.h
2177 static inline struct task_struct *next_thread(const struct task_struct *p)
2178 {
2179 return list_entry_rcu(p->thread_group.next,
2180 struct task_struct, thread_group);
2181 }
thread_group.nextとは、
include/linux/sched.hのtask_structのメンバー
1285 struct list_head thread_group;
list_headとは、
include/linux/list.h
41 struct list_head {
42 struct list_head *next, *prev;
43 };
list_entry_rcuとは?
include/linux/rculist.h
210 #define list_entry_rcu(ptr, type, member) \
211 container_of(rcu_dereference_raw(ptr), type, member)
spin_lock_irq のirqとは?
include/linux/spinlock.h
307 static inline void spin_lock_irq(spinlock_t *lock)
308 {
309 raw_spin_lock_irq(&lock->rlock);
310 }
include/linux/spinlock.h
220 #define raw_spin_lock_irq(lock) _raw_spin_lock_irq(lock)
include/linux/spinlock-api_up.h
59 #define _raw_spin_lock_irq(lock) __LOCK_IRQ(lock)
spin_local_irqに渡しているcurrent_sighand_siglockとは?
[conclusion]
utimeとstimeは、とりあえず全てのスレッド分足してそうだというとこまでは行ったがかなり消化不足気味
[気になるキーワード]
Hyper Threading
SMT (Simultaneous Multi Threading) 同時マルチスレッディング
SMP (Symmetric Multi Processing) 対象型マルチプロセシング
FORTRANで記述されコンパイラで自動並列化した数値解析のプログラムの実行時間を下記環境でtimeコマンドを使って測定したら下記の様な結果になった。
-実行環境-
OS: Cent OS
CPU: Intel Xeon Processor L5640 x 2
-並列数-
OMP_NUM_THREAD=12
-time コマンド結果-
real 84m23.521s
user 1010m2.767s
sys 0m7.199s
[reasoning]
user時間は、各コアのuser時間の合計となるためスレッド並列化して実行したコマンドでは、real時間よりも長くなることがある?
[research]
適当なミラーサイトからソースを取ってくる。
後、linuxカーネル(2.6.34)のソースも取ってくる。
まずは、タイムコマンドのmain関数
-time.c: main
632 main (argc, argv)
633 int argc;
634 char **argv;
635 {
636 const char **command_line;
637 RESUSE res;
…
640 run_command (command_line, &res);
641 summarize (outfp, output_format, command_line, &res);
run_commandという関数を見てみる
-time.c: run_command
597 static void
598 run_command (cmd, resp)
599 char *const *cmd;
600 RESUSE *resp;
601 {
…
605 resuse_start (resp);
…
614 execvp (cmd[0], cmd);
…
623 if (resuse_end (pid, resp) == 0)
timeコマンドで指定したコマンドをexecvp関数で実行している.
execvp関数の前後で呼んでいるresuseで始まる関数を次に見てみる
-resuse.c: resuse_start
46 void
47 resuse_start (resp) //resuseは、resource use startの略と思われる。
48 RESUSE *resp;
49 {
50 #if HAVE_WAIT3
51 gettimeofday (&resp->start, (struct timezone *) 0);
52 #else
53 long value;
54 struct tms tms;
55
56 value = times (&tms); // man によると返り値は過去のある時点からのtick
57 resp->start.tv_sec = value / HZ; // HZ は、CPUクロックか? 確証は得られてない
58 resp->start.tv_usec = value % HZ * (1000000 / HZ);
59 #endif
60 }
現在のクロックカウント(と言っていいのか?)をHZで割って時刻をresp->start.tvに保持する
-resuse.c: resuse_end
117 resp->elapsed.tv_sec -= resp->start.tv_sec; // real time (sec)?
124 resp->elapsed.tv_usec -= resp->start.tv_usec; // real time (micro sec)?
コマンド実行後に省略したが同様にCPU時刻を取得して実行前の時刻を引いている。=> 正味実行にかかった時間(real time)を算出。
struct tmsとは何か?
struct tms -> linux/times.h
6 struct tms {
7 __kernel_clock_t tms_utime; // user time
8 __kernel_clock_t tms_stime; // system time
9 __kernel_clock_t tms_cutime; // child process user time
10 __kernel_clock_t tms_cstime; // child process system time
11 };
__kernel_clock_t -> linux/types.h
79 typedef __kernel_clock_t clock_t;
-time.c : summarize
320 static void
321 summarize (fp, fmt, command, resp)
322 FILE *fp;
323 const char *fmt;
324 const char **command;
325 RESUSE *resp;
326 {
-kernel/sys.c 912 void do_sys_times(struct tms *tms)
921 tms->tms_utime = cputime_to_clock_t(tgutime);
922 tms->tms_stime = cputime_to_clock_t(tgstime);
923 tms->tms_cutime = cputime_to_clock_t(cutime);
924 tms->tms_cstime = cputime_to_clock_t(cstime);
thread_group_timesとは
kernel/sched.c
3398 void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
3399 {
3400 struct task_cputime cputime;
3401
3402 thread_group_cputime(p, &cputime);
3403
3404 *ut = cputime.utime;
3405 *st = cputime.stime;
3406 }
kernel/posix_cpu_timers.c
234 void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
235 {
236 struct sighand_struct *sighand;
237 struct signal_struct *sig;
238 struct task_struct *t;
239
240 *times = INIT_CPUTIME;
241
242 rcu_read_lock();
243 sighand = rcu_dereference(tsk->sighand);
244 if (!sighand)
245 goto out;
246
247 sig = tsk->signal;
248
249 t = tsk;
250 do {
251 times->utime = cputime_add(times->utime, t->utime);
252 times->stime = cputime_add(times->stime, t->stime);
253 times->sum_exec_runtime += t->se.sum_exec_runtime;
254
255 t = next_thread(t);
256 } while (t != tsk);
257
258 times->utime = cputime_add(times->utime, sig->utime);
259 times->stime = cputime_add(times->stime, sig->stime);
260 times->sum_exec_runtime += sig->sum_sched_runtime;
261 out:
262 rcu_read_unlock();
263 }
include/asm-generic/cputime.h
12 #define cputime_add(__a, __b) ((__a) + (__b))
next_thread(t);とは
include/linux/sched.h
2177 static inline struct task_struct *next_thread(const struct task_struct *p)
2178 {
2179 return list_entry_rcu(p->thread_group.next,
2180 struct task_struct, thread_group);
2181 }
thread_group.nextとは、
include/linux/sched.hのtask_structのメンバー
1285 struct list_head thread_group;
list_headとは、
include/linux/list.h
41 struct list_head {
42 struct list_head *next, *prev;
43 };
list_entry_rcuとは?
include/linux/rculist.h
210 #define list_entry_rcu(ptr, type, member) \
211 container_of(rcu_dereference_raw(ptr), type, member)
spin_lock_irq のirqとは?
include/linux/spinlock.h
307 static inline void spin_lock_irq(spinlock_t *lock)
308 {
309 raw_spin_lock_irq(&lock->rlock);
310 }
include/linux/spinlock.h
220 #define raw_spin_lock_irq(lock) _raw_spin_lock_irq(lock)
include/linux/spinlock-api_up.h
59 #define _raw_spin_lock_irq(lock) __LOCK_IRQ(lock)
spin_local_irqに渡しているcurrent_sighand_siglockとは?
[conclusion]
utimeとstimeは、とりあえず全てのスレッド分足してそうだというとこまでは行ったがかなり消化不足気味
[気になるキーワード]
Hyper Threading
SMT (Simultaneous Multi Threading) 同時マルチスレッディング
SMP (Symmetric Multi Processing) 対象型マルチプロセシング
[Visual Studio C++] PEバイナリのエクスポートされたシンボル
PEバイナリのエクスポートされたシンボル名を確認する
漢は黙ってバイナリエディタといきたいとこだけど
今回は、MSさんのツール(dumpbin)を使います。
このdumpbinは、Visual Studioを使うと [Install Direcotry]\VC\bin にインストールされます。
ここは、PATHが通ってないし、dumpbinが使うライブラリがあるPATHがサーチパスに含まれてないため、dumpbin.exeと同一ディレクトリにあるバッチファイル vcvars32.bat を実行する必要があります。
そして、
dumpbin /EXPORT input.dll
とすることでシンボル名を確認することができる。
漢は黙ってバイナリエディタといきたいとこだけど
今回は、MSさんのツール(dumpbin)を使います。
このdumpbinは、Visual Studioを使うと [Install Direcotry]\VC\bin にインストールされます。
ここは、PATHが通ってないし、dumpbinが使うライブラリがあるPATHがサーチパスに含まれてないため、dumpbin.exeと同一ディレクトリにあるバッチファイル vcvars32.bat を実行する必要があります。
そして、
dumpbin /EXPORT input.dll
とすることでシンボル名を確認することができる。
[c言語] Windows と Linux の共有ライブラリ
分けあってWindows向けの共有ライブラリ(dll) と Linux向けの共有ライブラリ(so) を
一つのC言語のソースで用意する必要が生じだ。
後にも先にもこれ一回限りな気がするけど一応メモ
検証環境は、
Windows 7 64bit版 C Compiler: gcc ライブラリを使う言語とコンパイラ Delphi XE2
Linux (RHEL) C Compiler: gcc ライブラリを使う言語とコンパイラ Fortran 90 pgfortran
まずは、ヘッダファイルとソース
add.h
#ifndef ADD_H
#define ADD_H
int add_(int *a, int *b)
int devide_(float *a, float *b, float *c)
#endif
一つのC言語のソースで用意する必要が生じだ。
後にも先にもこれ一回限りな気がするけど一応メモ
検証環境は、
Windows 7 64bit版 C Compiler: gcc ライブラリを使う言語とコンパイラ Delphi XE2
Linux (RHEL) C Compiler: gcc ライブラリを使う言語とコンパイラ Fortran 90 pgfortran
まずは、ヘッダファイルとソース
add.h
#ifndef ADD_H
#define ADD_H
int add_(int *a, int *b)
int devide_(float *a, float *b, float *c)
#endif
add.c
#include<stdio.h>
int add_(int *a, int *b){
int c;
c = *a + *b;
return c;
}
int devide_(float *a, float *b, float *c){
*c = *a / *b;
return 0;
}
ポイントは、引数がすべて参照渡しになっている点です。 Fortranが参照渡しがデフォルトなためです。 また、関数名がアンダースコアで終わっているのは、また後で。。。
お次は、コンパイル
まずは、Windowsで
gcc -shared -m32 -o add.dll add.c
-m32 は、32bi tPEバイナリを出力するためのオプションでdllを使う、アプリケーション(exe)が32bitであるため。
次に、Linuxで
gcc -fPIC -shared -o libadd.so add.c
-fPICは、位置独立コード(Position Independent Code)というメモリのどのアドレにもロード可能にするためのオプションです。
そして、使う側。
まずは、Delphi
unit use; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm6 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; TAdd = function(a : PInteger; b : PInteger) : integer ; stdcall; TDevide = function(a : PSingle; b : PSingle; c : PSingle) : integer ; stdcall; var Form6: TForm6; implementation {$R *.dfm} procedure TForm6.Button1Click(Sender: TObject); var ret : integer; a,b : integer; c,d,e : single; Handle : THandle; Add : TAdd; Devide : TDevide; begin a := 4; b := 2; c := 4.0; d := 2.0; Handle := LoadLibrary('add.dll'); if Handle <> 0 then begin @Add := GetProcAddress(Handle, 'add_'); if @Add <> nil then begin ret := add(@a, @b); ShowMessage(IntToStr(ret)); end; @Devide := GetProcAddress(Handle, 'devide_'); if @Devide <> nil then begin ret := devide(@c, @d, @e); ShowMessage(FloatToStr(e)); end; FreeLibrary(Handle); end; end; end.
関数をtypedefして、GetProcAddress にて関数のあるアドレスを取得する。
次は、Linux上のFortran
interface節を記述したインクルードファイルを作成
addf.h
interface
integer function add(a,b)
integer a,b
end function add
integer function devide(a,b,c)
real a,b,c
end function devide
end interface
次にFortranのソース本体
program test
include 'addf.h'
integer c,d
real e,f,g
c=4
d=2
e=4.0
f=2.0
d = add(c,d)
i = devide(e,f,g)
write(*,*) d,g,i
end program test
そしてコンパイル
pgfortran -I./include -L./lib -ladd src/use.f
-l で使用するライブラリを指定します。
また、Fortranの場合、関数名は、アンダースコアがついたシンボルを探すのでCの関数名には、アンダースコアをつける必要があります。
登録:
投稿 (Atom)