TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2008年2月7日 星期四

Queer Windows SDK

windows.h只有定義WINVER,可是SDK的objbase.h全部都是以_WIN32_WINNT的值和_WIN32_DCOM來打開DCOM結構,結果兩個都沒有定義。
根據這頁的介紹,WINVER和_WIN32_WINNT是差不多的,可是我不明白為什麼一個只定義WINVER,另一個只用_WIN32_WINNT,剛好錯開。
最後只好自己定義_WIN32_DCOM才能正常使用。

CJK and Hiragana characters in Unicode

CJK通用文字範圍: U+4E00 ~ U+9FFF
平假名範圍: U+3040 ~ U+309F

2008年2月6日 星期三

Order of I/O redirecting

在shell使用的I/O重導,其行為其實還有很多有趣的部分。一般常使用的就是<>,但是它們其實不只能重導stdin和stdout,重導的方向也不只有檔案或裝置而已。
<>其實前方可以加數字,就是file descripter,若不特別指明,那麼<預設會是0<>預設是1>,其中0即為stdin的file descripter,1為stdout的file descripter[?],而2就是stderr了。[?]
因此I/O重導的真正格式為:
M<N
M>N
其中M為file descripter,N為某個檔案[?]。而如果要把fd導向給另一個fd,就要用下列格式:
M>&N
其中M和N都是file descripter。
然而依然要小心一個小問題,就是重導的次序不同,效果也會有不同。
考慮以下的狀況:
$ cat > test.c
#include <stdio.h>
int main( int argc, char * argv[] ) {
    puts( "This is stdout." );
    fputs( stderr, "This is stderr." );
    return 0;
}
^D
$ gcc test.c -o test
$ ./test >output.txt 2>&1
$ ./test 2>&1 >output.txt
有趣的是,第一次在螢幕上什麼都沒顯示,而output.txt裡會找到那二個句子,但是第二次卻會在螢幕上顯示`This is stderr.',output.txt只有`This is stdout.'。表面看起來結果至少要相反才對呀?
因為第一種寫法,代表stdout先被dup2到output.txt,然後stderr才被dup2到被更改過的stdout,因此兩個都會進入output.txt。
而第二種寫法,則是stderr dup2到stdout,這時stdout還是連接在console上,不管之後stdout有沒有被更動,它就是會輸出到console,所以會變成stderr > console,stdout > output.txt。

2008年1月31日 星期四

防火牆修復

在遠端登入時如果不小心把防火牆搞爛了,可是非常麻煩的事,因為你很有可能無法再次遠端登入來修復防火牆;所以前幾天用python寫了個程式,在伺服器完全斷線時可以先讓防火牆恢復正常。
#! /usr/bin/env python
# -*- encoding: utf-8 -*-

import os, time, sys

def connect_test( *sites ):
        for site in sites :
                if os.system( "wget --tries=2 --timeout=120 -O - %s >/dev/null 2>&1" % site ) == 0 :
                        return True
        return False

flog = open( '/var/log/firewall_fix.log', 'a' )
timestamp = time.strftime( '%Y/%m/%d %H:%M' )

if connect_test( 'http://www.google.com/' ):
        print >> flog, "%s\tSuccess and do nothing.\n" % timestamp
else:
        try:
                if os.system( 'iptables-restore <%s >/dev/null 2>&1' % sys.args[1] ) != 0 :
                        raise OSError
                else:
                        print >> flog, "%s\tFirewall fixed. ( Use `%s'. )\n" % ( timestamp, sys.args[1] )
        except ( IndexError, OSError ):
                os.system( 'iptables -F' )
                for chain in [ 'INPUT', 'OUTPUT', 'FORWARD' ] :
                        os.system( "iptables -P %s ACCEPT" % chain )
                print >> flog, "%s\tFirewall fixed. ( Flush all. )\n" % timestamp

flog.close()

中間的連線測試其實滿dirty的[?],不過目前想不到其他更好的辦法。
噢,對了,Linux only。
2008/2/08 edited. Few code changed.

2008年1月30日 星期三

/dev/null的用處

在一個程式裡呼叫其他程式時,難免會有一些訊息跑出來,而當你不希望它出現時,可以利用I/O redirect導向到/dev/null裡。簡單地形容就是....垃圾筒。

2008年1月28日 星期一

getch()的POSIX實作

#include <stdio.h>
#include <termios.h>

char getch(void) {
        char buf = 0;
        struct termios old = {0};
        if (tcgetattr(0, &old) < 0)
                perror("tcsetattr()");
        old.c_lflag &= ~ICANON;
        old.c_lflag &= ~ECHO;
        old.c_cc[VMIN] = 1;
        old.c_cc[VTIME] = 0;
        if (tcsetattr(0, TCSANOW, &old) < 0)
                perror("tcsetattr ICANON");
        if (read(0, &buf, 1) < 0)
                perror ("read()");
        old.c_lflag |= ICANON;
        old.c_lflag |= ECHO;
        if (tcsetattr(0, TCSADRAIN, &old) < 0)
                perror ("tcsetattr ~ICANON");
        return (buf);
}

int main() {
        char key;
        printf("Press 'x' to exit...\n");
        while((key=getch()) && (key != 'x'))
                printf ("you pressed %c\n", key);
        return(0);
}

Reference

直接觀看封裝/壓縮過的檔案

Unix-like的紀錄檔通常在經過一定時間後就會壓縮為gz檔,為此可以使用如下的指令直接閱讀,不需要真正解開成一個檔案:
gzip -cd file.gz | less
如果壓縮過之前還被封裝過,就要換個程式:
tar -ztf file.tar.gz | less
於是,再一次地我們要發揮程式設計員的美德之一:懶惰。
每次都要打那些指令太煩了,所以我寫了一個bash shell,名叫xless[?],自己根據檔案類型展開。
#! /bin/bash

if [ $# -eq 1 ] ; then                          # 只接受一個參數
        if [[ $1 =~ '\.tar\.gz$' ]] ; then      # 以regex過濾*.tar.gz
                exec tar -ztf $1 | less
        elif [[ $1 =~ '\.gz$' ]] ; then         # 再過濾*.gz
                exec gzip -cd $1 | less
        else
                echo 'Invalid filename.'
        fi
else
        echo 'Must takes one argument.'
fi
然後再把這個檔案改成可執行檔,export到PATH裡,就可以隨時取用了。

Copy Right真絕....

剛才為了要寫一個能在Windows[?]下控制防火牆的程式,但是測試用的code竟然不能用,因為它需要netfw.h,而之前下載的Windows® Server 2003 SP1 Platform SDK裡沒有包含;仔細看一下文件才發現這已經不是最新的Platform SDK,而且也不會再更新了,目前最新的是Windows® Server 2003 R2 Platform SDK,無奈的是它要通過WGA認證才能下載。
其實我也不是在說微軟怎樣,只是這樣會讓我的compile-time需求又多上一筆....