回精華區
作者tsaikd.bbs@tsaikd.twbbs.org (千人斬) 看板: plan
標題Re: [程式] script 快速的跟 ITOC BBS 的公版同步更新
時間地下惡魔城 (2005/06/08 Wed 18:44:34)
#!/bin/bash
# ========================================================================
# 程式目的:
#     讓 BBS Code 管理者可以自動取得 ITOC BBS 最新公版的程式碼及精華區
#     並且快速合併新舊版本
#
# 使用說明:
#     01. 請先將本 script 的權限更改為可執行:
#           chmod 700 itoc_bbs.sh
#     02. SOURCE_DIR 請在設定區中設定
#         抓下來的程式碼將會放在 "SOURCE_DIR"/bbs_XXXXXX (XXXXXX 為版本日期)
#         抓下來的精華區將會放在 "SOURCE_DIR"/gem_XXXXXX (XXXXXX 為版本日期)
#     03. 在合併程式碼之前
#         請先確定 "SOURCE_DIR" 中有兩個以上的 ITOC BBS 的 sources
#         一個是新的,一個是舊的
#         本 script 只會檢查最新的兩個 sources code
#         而且其資料需放在 "SOURCE_DIR"/bbs_XXXXXXXX ( XXXXXXXX 為版本日期 )
#         ( 建議用本程式抓檔案,以確定格式相容 )
#     04. 請定期清理 "SOURCE_DIR" 以免佔用大量硬碟空間
#         只要留最新的兩個 sources code 及其目錄就夠了
# ========================================================================
# 版權宣告:
#     本程式為免費軟體
#     歡迎以任何形式散佈
#     請勿做商業行為
# 寫作環境:
#     Gentoo Linux
#     Kernel 2.6.11-gentoo-r8
# 臭蟲回報:
#     tsaikd <tsaikd@gmail.com>
# 歷史紀錄:
#     2005/06/01 tsaikd         首次釋出
#     2005/06/07 tsaikd		修改取得檔案列的方式
#                               並檢查是否需要下載
#     2005/06/07 tsaikd         修正一些造成空字串的 bug
#     2005/06/08 tsaikd		新增必要程式自我檢測機制
#     2005/06/10 tsaikd         增加一些人性化的控制,防止二度更新
#     2005/08/04 tsaikd		將 get 跟 merge 兩個 script 合併
#     2005/08/05 tsaikd		修改檢查參數的機制
#     2005/08/21 tsaikd		新增檔案時不顯示 cp 錯誤
#     2005/09/22 tsaikd		解決 sym link 會產生的問題
#     2005/10/18 tsaikd		修改一些笨語法
# ========================================================================
#                               程式自我檢測
# ========================================================================
PROGRAM_LIST="awk basename cat clear cp cut date df diff grep head ls lynx mv patch rm tail tar tr wget"
for i in $PROGRAM_LIST ; do
  if [ -z "$(type -p $i)" ] ; then
    echo "[ERROR] Can't find $i in your system !"
    exit 1
  fi
done
# ========================================================================
#                                  設定區
# ========================================================================
ITOC_WEB_SITE="http://processor.tfcis.org/~itoc/" # ITOC 的網站
SOURCE_DIR="/home/bbs/tmp"

START_LINE="vvvvvvvvvvvvvvvvvvvvv==== start ====vvvvvvvvvvvvvvvvvvvvvvvvv"
  END_LINE="^^^^^^^^^^^^^^^^^^^^^====  end  ====^^^^^^^^^^^^^^^^^^^^^^^^^"
 NEXT_LINE="----------------------- next file ---------------------------"

HOME="$(cd;pwd)"
TIME='$(date "+%F %T")'
# ========================================================================
#                                 程式開始
# ========================================================================

function echoerr () { [ -w "/dev/stderr" ] && echo "$*" > /dev/stderr || echo "$*" ; }

function pause () { read -u 1 -p "Press [ENTER] to continue" ; }

# check source directory
if [ ! -d "$SOURCE_DIR" ] ; then
  echoerr "[ERROR] source dir ( $SOURCE_DIR ) doesn't exist !"
  exit 1
fi

function get_itoc_bbs () {
  cd "$SOURCE_DIR"
  lynx -dump "$ITOC_WEB_SITE" > file_list.tmp

  BBS_FILE="$(basename `cat file_list.tmp | grep -E "[0-9]*\. .*MapleBBS.*\.tgz" | tail -n 1 | awk '{print $2}'`)"
  BBS_DATE="bbs_$(echo $BBS_FILE | tr -s "-" " " | awk '{print $3}')"

  GEM_FILE="$(basename `cat file_list.tmp | grep -E "[0-9]*\. .*itoc_gem.*\.tgz" | tail -n 1 | awk '{print $2}'`)"
  GEM_DATE="gem_$(echo $GEM_FILE | tr -s "_" " " | tr -s "." " " | awk '{print $3}')"

  rm -f file_list.tmp

  if [ -f "${BBS_FILE}" ] ; then
    echo "[WARNING]"
    echo "Your BBS source code is the newest!"
    echo "You don't need to update."
  else
    wget "${ITOC_WEB_SITE}/${BBS_FILE}"
    tar xzpf "$BBS_FILE" -C "$SOURCE_DIR"
    mv bbs "$BBS_DATE"
  fi

  if [ -f "${GEM_FILE}" ] ; then
    echo "[WARNING]"
    echo "Your BBS ITOC gem code is the newest!"
    echo "You don't need to update."
  else
    wget "${ITOC_WEB_SITE}/${GEM_FILE}"
    tar xzpf "$GEM_FILE" -C "$SOURCE_DIR"
    mv gem "$GEM_DATE"
  fi
}

function update_itoc_gem () {
  BOARDNAME="$1"
  TARPATH="${HOME}/gem/brd/${BOARDNAME}"
  GEM_FILE="$(ls "$SOURCE_DIR" | awk '/^gem_/{print}' | tail -n 1)"
  if [ -z "$GEM_FILE" ] ;then
    echoerr "update gem error: cannot find gem file in $SOURCE_DIR"
    exit 2
  fi
  GEM_PATH="${SOURCE_DIR}/${GEM_FILE}"
  if [ ! -d "$TARPATH" ] ; then
    echoerr "update gem error: $BOARDNAME doesn't exist in $TARPATH"
    exit 3
  fi

  rm -rf "$TARPATH"
  cp -r "$GEM_PATH" "$TARPATH"

}

function merge_itoc_bbs () {
  cd "$SOURCE_DIR"
  declare -i NUM=0
  unset NEW_BBS
  unset OLD_BBS
  for i in $(ls -dr bbs_*) ; do
    ((NUM++))
    if [ "$NUM" -eq 1 ] ; then
      NEW_BBS="$i"
    elif [ "$NUM" -eq 2 ] ; then
      OLD_BBS="$i"
    else
      break
    fi
  done

  if [ -z "$NEW_BBS" ] || [ -z "$OLD_BBS" ] ; then
    echoerr "[ERROR] Cannot find more than one BBS source directory!"
    exit 4
  fi

  diff -ruNp "$OLD_BBS" "$NEW_BBS" | grep -E "diff " > merge_bbs.list.tmp

  while read BUF ; do
    if [ -n "$(echo "$BUF" | grep -E "^Files .* and .* differ$")" ] ; then
      MERGE_FILE="$(echo "$BUF" | awk '{print $2}' | cut -c 13-)"
      MERGE_FILE_NAME="$(basename "$MERGE_FILE")"
      OLD_BBS_FILE="${SOURCE_DIR}/${OLD_BBS}${MERGE_FILE}"
      NEW_BBS_FILE="${SOURCE_DIR}/${NEW_BBS}${MERGE_FILE}"
      SRC_BBS_FILE="${HOME}${MERGE_FILE}"

      echo "$BUF"
      printf "Do you want to update the file ? [Y/n] " ; read ANS
      [ "$ANS" != "n" ] && cp -df "$NEW_BBS_FILE" "$SRC_BBS_FILE"
    elif [ -n "$(echo "$BUF" | grep -E "^diff ")" ] ; then
      MERGE_FILE="$(echo "$BUF" | awk '{print $3}' | cut -c 13-)"
      MERGE_FILE_NAME="$(basename "$MERGE_FILE")"
      OLD_BBS_FILE="${SOURCE_DIR}/${OLD_BBS}${MERGE_FILE}"
      NEW_BBS_FILE="${SOURCE_DIR}/${NEW_BBS}${MERGE_FILE}"
      SRC_BBS_FILE="${HOME}${MERGE_FILE}"

      if [ -z "$(diff -ruNp "$SRC_BBS_FILE" "$NEW_BBS_FILE")" ] ; then
        echo "$SRC_BBS_FILE is updated!"
      elif [ -z "$($BUF > merge_bbs.patch.tmp ; \
        cp -f "$SRC_BBS_FILE" "$MERGE_FILE_NAME" ; \
        patch -r /dev/null --no-backup-if-mismatch \
          "$MERGE_FILE_NAME" merge_bbs.patch.tmp &>/dev/null ; \
        diff -ruNp "$SRC_BBS_FILE" "$MERGE_FILE_NAME" ; \
        rm -f "$MERGE_FILE_NAME" )" ] ; then
        echo "$SRC_BBS_FILE can't be patched automatically!"
        echo "( Maybe it had been updated )"
        echo "You should check \"$MERGE_FILE_NAME\" by yourself!"
        pause
      else
        $BUF > merge_bbs.patch.tmp
        cp -f "$SRC_BBS_FILE" "$MERGE_FILE_NAME" &>/dev/null

        echo "Between \"$OLD_BBS_FILE\" \"$NEW_BBS_FILE\""
        printf "Do you want to read patch contents ? [y/N] " ; read ANS
        if [ "$ANS" == "y" ] ; then
          echo "$START_LINE"
          cat merge_bbs.patch.tmp
          echo "$END_LINE"
        fi

        echo
        printf "Do you want to merge it automatically ? [Y/n] " ; read ANS
        if [ "$ANS" != "n" ] ; then
          patch --no-backup-if-mismatch "$MERGE_FILE_NAME" merge_bbs.patch.tmp
          if [ "$?" -ne 0 ] ; then
            echoerr "[ERROR] when merge $MERGE_FILE_NAME"
            pause
          fi

          echo
          echo "Between \"$NEW_BBS_FILE\" \"merged $MERGE_FILE_NAME\""
          if [ ! -f "$MERGE_FILE_NAME" ] ; then
            echo "This file doesn't exist in new version!"
            printf "Do you want to delete it ? [Y/n] " ; read ANS
            [ "$ANS" != "n" ] && rm -f "$SRC_BBS_FILE"
          elif [ -z "$(diff -ruNp "$NEW_BBS_FILE" "$MERGE_FILE_NAME")" ] ; then
            echo "They are the same files. And update it automatically!"
            cp -df "$MERGE_FILE_NAME" "$SRC_BBS_FILE"
            rm -f "$MERGE_FILE_NAME"
          else
            printf "Do you want to read the differences ? [y/N] " ; read ANS
            if [ "$ANS" == "y" ] ; then
              echo "$START_LINE"
              diff -ruNp "$NEW_BBS_FILE" "$MERGE_FILE_NAME"
              echo "$END_LINE"
            fi

            if [ -z "$(diff -ruNp "$SRC_BBS_FILE" "$MERGE_FILE_NAME")" ] ; then
              echo "Between \"$SRC_BBS_FILE\" \"merged $MERGE_FILE_NAME\""
              echo "They are the same files. No need to update!"
              rm -f "$MERGE_FILE_NAME"
            else
              echo
              echo "After merging \"$SRC_BBS_FILE\","
              printf "Do you want to update it automatically ? [Y/n] " ; read ANS
              if [ "$ANS" != "n" ] ; then
                cp -df "$MERGE_FILE_NAME" "$SRC_BBS_FILE"
                rm -f "$MERGE_FILE_NAME"
              else
                echo "$MERGE_FILE_NAME is keeping in ~/tmp"
              fi
            fi
          fi
        fi
        pause
      fi
    fi
    read -n 0 ; [ $? -eq 0 ] && echo "$NEXT_LINE"
  done < merge_bbs.list.tmp
  rm -f merge_bbs.patch.tmp
  rm -f merge_bbs.list.tmp

  echo
  echo "**** == Remember to compile your BBS again !! == ****"
  echo
}

function show_help () {
  echo "Usage of $0 :"
  echo '  -h | --help    : show help'
  echo '  -g | --get     : get the newest sources version of itoc bbs'
  echo '  -m | --merge   : merge and update your itoc bbs to the newest version'
  echo '  -u "BOARDNAME" : update ITOC gem to "BOARDNAME"'
}

ARGV="$*"
[ "$#" -eq 0 ] && show_help && exit
while [ -n "$ARGV" ] ; do unset PARA_KEY
  PARA="$(printf "%s" "$ARGV" | awk '{if(NF<2){print $1}else{if(match($2,"^-")){print $1}else{print $1" "$2}}}')"
  JUMP="$(printf "%s" "$PARA" | awk '{print NF}')"
  LENGTH="$(printf "%s" "$PARA"|awk '!/^--/{print length($1)}/^--/{print "0"}')"
  case " $PARA " in
  *\ -h*|*" --help "*) PARA_KEY="h"
    show_help ;;
  *\ -g*|*" --get "*) PARA_KEY="g"
    get_itoc_bbs ;;
  *\ -m*|*" --merge "*) PARA_KEY="m"
    merge_itoc_bbs ;;
  *\ -u*) PARA_KEY="u"
    [ "$JUMP" -eq 2 ] && PARA_VAL="$(printf "%s" "$PARA" | awk '{print $2}')"
    update_itoc_gem "$PARA_VAL" ;;
  esac
  if [ "$LENGTH" -gt 2 ] && [ -n "$PARA_KEY" ] ; then
    ARGV="$(printf "%s" "$ARGV" | awk '{gsub("'$PARA_KEY'","",$1);print}')"
  else
    [ -z "$PARA_KEY" ]  && \
      echoerr "[ERROR] This program can't recognize the parameter : \"$PARA\" !"
    [ "$JUMP" -lt 3 ] && shift $JUMP && ARGV="$*"
  fi
done

# ========================================================================
#                                 程式結束
# ========================================================================


--
 千        人         斬    KD !! 地下惡魔城 telnet://bbs.tsaikd.twbbs.org
 K Delete         殺殺殺 殺到你脫褲子 "放屁" !!
 i    ~~      ▄▃▂▁       ︿◎    ︿◎    ︿◎ 快逃啊!!
 l    ~~ ◤ ̄ ̄                  ◤﹀    ◤﹀    ◤﹀
 o   ~ /∣                  ..﹀〉....﹀〉....﹀〉

--
  Origin:  成大資訊˙地下惡魔城  tsaikd.twbbs.org 
  Author: tsaikd tsaikd.v1.dorm.ncku.edu.tw 發表
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻