2013年12月5日 星期四

modify geanyvc for support subversion 1.8.4

更換 SVN 1.8.4 後發現我常用的 geany + geanyvc &meld 卻不能使用 了 .
主要原因是因為  geanyvc 沒有辦法找到 .svn 資料夾 .
看一下 google 上的討論 ,  只要修改兩個小地方就可以用了, 那就動手升級 geany 和 geanyvc 吧 !!

下載 source code .
geany :  "geany-1.23.1.tar.gz"
geany plugins :  "geany-plugins-1.23.tar.gz"


先編譯 geany:
A. untar source code .
B. into source tree , do ./configure
    這時候會遇到問題, 缺少 gtk ... glib 等....
    $> sudo apt-get install gtk+-2.0
    如果缺少 intltool-update , 就在安裝一次 .
    $> sudo apt-get install intltool 

C.  make
D. sudo make install

這樣就有 geany 1.23.1 版了.不過記住移除就的 geany , 避免有所衝突.

接著編譯 geany-plugins :

A. untar source code.
B. 修改 ..../geany-plugins-1.23/geanyvc/src/vc_svn.c file.

static gchar * get_base_dir(const gchar * path)
{

 .................................................

                break;
        }
        while (strcmp(base, base_prev) != 0);

//---- Add patch by Jeff Hsieh.

   if (base_prev == NULL)
   {
       /* fallback for Subversion 1.7: try to climb up the tree until we
        * find a .svn subdirectory */
        base_prev = find_subdir_path(path, ".svn");
   }


        g_free(base);
        return base_prev

}

還有將下列兩行移除.

static gboolean in_vc_svn(const gchar * filename)
{

 .............................
        gboolean ret = FALSE;
        gchar *std_output;

//---- Remove by Jeff Hsieh.
//      if (!find_dir(filename, ".svn", FALSE))
//              return FALSE;


        if (g_file_test(filename, G_FILE_TEST_IS_DIR))
                return TRUE;
 

 .................................

}

這些修改在 google 上都找的到 , 詳細討論請自行到 google 上搜尋.

C. into source tree of top .
    $> ./configure --enable-geanyvc
    預設應該會打咖 geanvc , 和其他一堆 plugins .... 不過我確保有我要的 geanyvc , 所以特別加註 .

D. make
E. sudo make install


完成了.... 這樣的 geany + geanyvc 就可以支援 meld 的 diff viewer 了 .......

















2013年11月30日 星期六

install Subversion Ver:1.8.4 in ubuntu 12.04LTS

舊版本的SVN 會在每個目錄面都建立一個 .SVN 資料夾. 

新版的 SVN (好像 1.7 以上) 就不會有這樣的狀況了 , 
只有根目錄建立一個.svn folder , 這樣有些好處, 我常常找一個接近的應用碼, 然後將整個目錄複製成另外一個名稱,然後開始新的程式, 最後要 commit 的時候就出現大問題的,因為我也複製的一個 .svn 資料夾,導致所有 svn 動作怪怪的 !! 新版就不會有這樣的問題了..

另外,可能不需要到處尋找.svn 資料夾, 所以 svn st 感覺好像有快一點.... 

不過要再 ubuntu 12.04LTS 上裝 SVN version 1.8.4就會出現一堆問題了 @@ .
我的習慣都是利用 source code 在環境上 make ; make install 的方式. 
好吧...自己來裝... 

A. Download subversion V1.8.4 source code form subversion  official side.
     "subversion-1.8.4.tar.gz"
B. The svn 1.8.4 need sqlite3 , so download sqlite3 source from offical side.
     "sqlite-autoconf-3080100.tar.gz"
C. If the SVN need suppoer http or https , need libserf & openSSH .
    #  The openSSH your can install with 
        "sudo apt-get install openssh-client openssh-server"
    # Download libserf source code .
        "serf-1.3.2.tar.bz2"
D. libserf 需要 scons  來編譯, 所以只好下載 scons-local-2.3.0.tar.gz 來用. 

 

下載完畢,可以開始動工 ,首先編譯 sqlite3 , 這邊沒有遇到問題 , 一般解開 , configure , make , make install ...就完成.

接著準備 libserf , 先將 scons 直接解開在 /usr/local/bin/ 下即可.接著解開 libserf .
在 libserf 資料夾內執行 "scons PREFIX=/usr/local"  , 接著執行  "sudo scons install" 這樣又完成了, 就可以在/usr/local/lib/ 下看到 libserf..xxxxx 的 so file .

可以開始編譯 svn 了 ,解開source code , 解開執行 ./configure --prefix=/usr/local , 接著 make , sudo make install . 就完成了 !! 

檢視看看svn 吧 , 利用 svn --version 可以看到下列訊息. 支援 http & https 了. 
如果沒有使用serf ,  就只有 ra_svn & ra_local 兩的項目  ! 




2013年4月16日 星期二

ext4 filesystem VS stat command.

這篇文章我不知道要如何命名比較恰當 , 主要會使用 mkfs.ext4 和 stat 這兩個utility 所以就簡單命名了 !!

在 embedded system 中 nand flash space 是很寶貴的 , 不能太浪費 !!
需求來了, 我需要計算要放入的資料大小(包含一堆目錄)然後建立一個 剛剛好大小的 image file , 這個 image file 需要包含 ext4 filesystem ,量產時只要將這個 image file 直接燒錄到eMMC 對應的partition 中即可.

問題是.... 現在我每次都計算部準確 .... 常常 空間不足夠 , 又不能浪費一堆空間 (這個是純資料 , Device 會使用 mount -o r ..... read-only type , 所以浪費的也用不到 !! )

先說 stat 吧 !!

stat 可以將檔案 , 資料夾所需要的 block & size都列印出來 , 指令如下:

  STAT="/bin/stat"
   size=`${STAT} -c%s $1`
   block=`${STAT} -c%b $1
`


也可以利用 stat 來知道是檔案還是資料夾

${STAT} ${dir_list} | grep -q "directory"
    if [ $? != 0 ];then
##        echo "###### FileStatus ${dir_list}"
        FileStatus ${dir_list}
    else
##        echo "###### DirectStatus ${dir_list}"
        DirectStatus ${dir_list}
        if [ DIRECT_COUNT != 0 ];then
            let DIRECT_COUNT=DIRECT_COUNT-1
        fi
    fi


然後用 shell file 計算所有資料夾需要的 size 和 block count .

這邊要注意 , ext2/ext4 的 block size 有 1024/2048 & 4096 區分 .
一樣會有內部斷裂問題 (小於 block size會使用一個 block 去儲存) .

stat -c%b 回應的值是 disk 的最小block 單位 目前都是 512 bytes.
或者可以用 stat -c%B 去讀取 確定的大小值 .
我寫了一個 xstat.sh shell scrip 去計算所有資料的大小 , 如下:

example :

[jeff@instant ec910-sdk]$ ./build/xstat.sh src/
file count:145
folder count:7
file size:2055196
folder size:94208
total need block:603
[jeff@instant ec910-sdk]$



這個 shell 統計出 需要 603 個 block 也就是需要 603 * 4096 bytes.


ext4 filesystem structure:



shell script 中的 getopt & getopts

在 linux shell 中我們常常用到 傳入一些參數 . 之前我都使用 getopts 的方式, 使用上都好好的 , example file 如下(片段):


while getopts ":O:h" opt; do
        echo "opt:${opt}"
        case ${opt} in
        ## ---- output size setting.
            O )
                OUT_BLOCK_SZ=${OPTARG}
            ;;

        ## ---- help menu.
            \? | h )
                ${MKMATE} color -fred "## Bad command ${OPTARG}...."
                Usage
                return 1
            ;;

        esac

    done


今天想要輸入 一堆其它的值 例如: <$> foo.sh -O 1234 dir_1 dir_2 dir_3. or
<$> foo.sh dir_1 dir_2 dir_3 ..... -O 1234
使用之前就的方式卻出問題, 這些 dir 訊息沒有辦法取出(maybe I got some mistake in getopts ),所以就換成使用 getopt 了, example 如下:


    args=`getopt O:h $@ `
    if [ $? != 0 ];then
        ${MKMATE} color -fred "## Bad command ${OPTARG}...."
        return 1
    fi

    set -- ${args}

    while [ -n "$1" ]
    do
        case $1 in

        ## ---- output size setting.
            -O )
                shift
                OUT_BLOCK_SZ=$1
            ;;

            -h | - )
                Usage
                return 1
            ;;

            \? )
                ${MKMATE} color -fred "## Bad command ${OPTARG}...."
                Usage
                return 1
            ;;

            -- )
                DIR_LIST=
            ;;

            * )
                if [ -z ${DIR_LIST} ];then
                    DIR_LIST="$1"
                else
                    DIR_LIST=${DIR_LIST}:$1
                fi

            ;;
        esac
        shift
    done


不管輸入方式是 <$>foo.sh -O 1234 dir_1 ..... or <$>foo.sh dir_1 ..... -O 1234
最後 srgs 都會 -O 1234 -- dir_1 dir_2 .....
接著用 set -- ${args} 就可以重新設定 $@ 參數 .
在利用 while 和 shift 就可以逐一取出想要的參數 , 利用 -- 當區隔就可以將 dir_1 dir_2 取入 .

我利用 : 將這些 dir 資料並起來, 有利於我的處理需求 !!



Reference :

http://changyy.pixnet.net/blog/post/25660234-%5Bbash%5D-%E5%B0%87%E6%AA%94%E6%A1%88%E5%85%A7%E7%9A%84%E5%AD%97%E4%B8%B2%E9%80%B2%E8%A1%8C%E5%8F%96%E4%BB%A3

2013年2月20日 星期三

auto mount NAS direct on /home/

最近因為需要處理NAS 上的資料 , 每天早上開機都要 mount 一次 , 麻煩 , 寫一個 shell 來自動 mount 吧 !!

開機完畢後只要執行這個 shell 就會將需要的 mount 好. 預設值是 Public & Software 資料夾 , mount 位置在 /home/${USER}/NAS/ , 並且會自動建立對應位置 , 如果需要額外資料夾 , 可以 使用 nas_mount.sh abc 的方式.
這個 shell 會檢查 NAS 是否在線上 (ping IP) .
也會自動檢查是否已經 mount 好了.

內容如下:


#!/bin/sh
#
# vi:set ts=4:

## ===== defind echo color
COLOR_ECHO="echo -e"        ## in Fedora the color echo need have -e argument.
COLOR_NORMAL="\033[0m"
COLOR_BOLD="\033[1m"
COLOR_RED="\033[31m"
COLOR_GREEN="\033[32m"
COLOR_YELLOW="\033[33m"
COLOR_BLUE="\033[34m"

## =====================================
## NAS Mount function.
## =====================================
function NAS_mount()
{
nas_dir="$1"
mnt_dir="$2"

## ---- echo some message .
${COLOR_ECHO} "${COLOR_BOLD}""${COLOR_BLUE}" \
                "## Mount NAS \"${nas_dir}\" director on \"${mnt_dir}\" ........" \
                "${COLOR_NORMAL}"

## ---- check mnt_dir exist
if [ ! -e "${mnt_dir}" ];then
    mkdir -p ${mnt_dir}
fi

## ---- check already mounted
_mounted=`cat /proc/mounts | grep NAS/${nas_dir} | awk '{print $2}'`
_mount_src=`cat /proc/mounts | grep NAS/${nas_dir} | awk '{print $1}'`

if [ -n "${_mounted}" ];then
    ${COLOR_ECHO} "${COLOR_BOLD}""${COLOR_GREEN}" \
                "    # NAS \"${_mount_src}\" Already mount on \"${mnt_dir}\"  ......" \
                "${COLOR_NORMAL}"
else

    _nas_aliv=`ping ${NAS_IP} -c 1 | grep errors  | sed 's/.*errors/errors/g' | sed 's/errors.*/errors/g' `
    if [ -z "${_nas_aliv}" ];then
        echo xxxxxxx | su -c " mount.cifs //192.168.2.6/${nas_dir} ${mnt_dir} -o user=jeff -o pass=xxxxxxxxx" > /dev/null 2>&1

    else
        ${COLOR_ECHO} "${COLOR_BOLD}""${COLOR_RED}" \
                    "NAS Server not ready \"${NAS_IP}\" ........" \
                    "${COLOR_NORMAL}"
    fi
fi


}

## ===== Mount NAS on System.
NAS_IP="192.168.2.6"


if [ -z "$1" ];then
    NAS_mount "Software" "/home/${USER}/NAS/Software"
    NAS_mount "Public" "/home/${USER}/NAS/Public"
else
    NAS_mount "${1}" "/home/${USER}/NAS/${1}"
fi

## =================

2013年2月18日 星期一

用 shell + crontab 固定發出 openkm report Mail.

最近因為 上級要知道 OpenKM(簡稱 OKM) 內容的更動狀況 , 需要每週 report 一次 !!
主要是看看這星期 OKM 內容有哪些人更動!!

Google 一下 有關 OKM 的 auto report  , 發現需要會 java script , 我不會 @@ !!

想說 , OKM 的 dashboard 可以看到 log 內容 , 應該 找一下 log file , 也會有吧 !!
找了半天 , 發現 /openkm-6.2.2-community/tomcat/repository/okmdb.log 內有我要的訊息 , 好吧 , 山不轉 人轉  , 寫一個 shell script + crontab 來執行 auto report 吧 !!

首先寫一個 shell , 由 okmdb.log 內容取出 document create/delete & check in 的項目
到一個 temp file , shell 如下:


#!/bin/sh
#
# vi:set ts=4:

#############################
## ===== defind echo color
#############################
COLOR_ECHO="echo -e"        ## in Fedora the color echo need have -e argument.
COLOR_NORMAL="\033[0m"
COLOR_BOLD="\033[1m"
COLOR_RED="\033[31m"
COLOR_GREEN="\033[32m"
COLOR_YELLOW="\033[33m"
COLOR_BLUE="\033[34m"

#############################
## ==== check log file exist.
#############################
OKMDB_LOG="/home/jeff/openkm-6.2.2-community/tomcat/repository/okmdb.log"
TEMP_FILE="/home/jeff/okm_report.txt"

if [ ! -e ${OKMDB_LOG} ];then
    ${COLOR_ECHO} "${COLOR_BOLD}""${COLOR_RED}" \
        "The log file \"${OKMDB_LOG}\" not exist !! " \
        "${COLOR_NORMAL}"

    exit
fi

#############################
## ====  Crate title
#############################
echo -e "ITEM\t\t\tDATE\t\t\tFILES\t\t\tUSER" > ${TEMP_FILE}
echo >> ${TEMP_FILE}

#############################
## ==== get document create event log.
#############################
DOC_CREATE=`cat ${OKMDB_LOG} | grep "CREATE_DOCUMENT" | sed 's/\ /:/g'`

IFS="
"
for list in ${DOC_CREATE} ; do
    IFS=','
    _date=`echo ${list} | awk '{print $3}' | sed 's/\..*//g' | sed 's/'\''//g' `
    _file=`echo ${list} | awk '{print $7}' | sed 's/'\''//g' | sed 's/\/okm\:root\///g' `
    _user=`echo ${list} | awk '{print $8}' | sed 's/'\''//g' | sed 's/)//g'`
    echo -e "CREATE\t\t${_date}\t\t${_file}\t\t${_user}" >> ${TEMP_FILE}
done
echo >> ${TEMP_FILE}

#############################
## ==== get document delete event log.
#############################
DOC_DELETE=`cat ${OKMDB_LOG} | grep "DELETE_DOCUMENT" | sed 's/\ /:/g'`

IFS="
"
for list in ${DOC_DELETE} ; do
    IFS=','
    _date=`echo ${list} | awk '{print $3}' | sed 's/\..*//g' | sed 's/'\''//g' `
    _file=`echo ${list} | awk '{print $6}' | sed 's/'\''//g' | sed 's/\/okm\:root\///g' `
    _user=`echo ${list} | awk '{print $7}' | sed 's/'\''//g' | sed 's/)//g'`
    echo -e "DELETE\t\t${_date}\t\t${_file}\t\t${_user}" >> ${TEMP_FILE}
done
echo >> ${TEMP_FILE}

#############################
## ==== get document modify event log.
#############################
DOC_CHECKIN=`cat ${OKMDB_LOG} | grep "CHECKIN_DOCUMENT" | sed 's/\ /:/g'`

IFS="
"
for list in ${DOC_CHECKIN} ; do
    IFS=','
    _date=`echo ${list} | awk '{print $3}' | sed 's/\..*//g' | sed 's/'\''//g' `
    _file=`echo ${list} | awk '{print $7}' | sed 's/'\''//g' | sed 's/\/okm\:root\///g' `
    _user=`echo ${list} | awk '{print $8}' | sed 's/'\''//g' | sed 's/)//g'`
    echo -e "CHECKIN\t\t${_date}\t\t${_file}\t\t${_user}" >> ${TEMP_FILE}
done
echo >> ${TEMP_FILE}

##############################
## ==== send notify mail
#############################
NOTIFY_MAIL="jeff@xxxxxxx.com.tw,ch@xxxxxxx.com.tw,emiliehuang@xxxxxxx.com.tw,alvin@xxxxxxx.com.tw,pp@xxxxxxx.com.tw"
#NOTIFY_MAIL="jeff@xxxxxxx.com.tw"

mail -s "Content report" ${NOTIFY_MAIL} <  ${TEMP_FILE}
rm -rf  ${TEMP_FILE}

## ==== remove log file ??

if [ ! -z "$1" ] && [ "$1" == "-d" ];then
    echo > ${OKMDB_LOG}
fi

#############################
接著 , 我不想每天(星期)都去檢查 report file , 就將這個 file 內容直接mail 給上級吧^^ !!



要讓 fedora 發  mail 其實蠻簡單的 用 "mail -s "Content report" ${NOTIFY_MAIL} <  ${TEMP_FILE}"
就可以了!!

不過要先設定 smtp 的內容 , google 一下 其實也不難 , 只要建立 /home/jeff/.mailrc 檔案, 且.mailrc 內容填入下列即可:

set from=Server_AUTO<jeff@xxxxxx.com.tw> smtp=xxxx.com.tw
set smtp-auth-user=jeff@xxxx.com.tw smtp-auth-password=*******

set smtp-auth=login





上面有些個人訊息 , 就用 xxxx 和 **** 代替 !!

收到 mail 的內容就會如下:


ITEM            DATE            FILES            USER

 CREATE        2013-02-06:10:28:40        share/data_sip_image_ec510/sip/Image/English/Lower/btn_backspace_press.png        alvin
 CREATE        2013-02-06:10:29:18        share/data_sip_image_ec510/sip/Image/English/Upper/btn_backspace_press.png       alvin
..........