2011年5月29日 星期日

找到船長了嗎?還是要自告奮勇呢?


上周看到海賊王的動畫劇情,魯夫跟艾斯小時候的故事,恰好談到關於大家都想當船長的事,最後則是碰到一位老船長,道述著船長,是一種讓大家想要跟著他的人。並不是強硬出來誰要當船長就能當得上的。


最近常閒聊收集資料,如果船長當作創業來說,在大公司當船員所獲得的並不會少於自己當船長出來闖蕩時,那還有什麼理由想當船長呢?因為只想做自己想做的事嗎?我覺得這樣的念頭還不太夠。例如創業時,發現自己的構想實踐後無法立足於大海時,這時候不就會變相去找其他支持航海的資源,例如接 case 做事等,那不就久而久之又變成去幫別人做事,而不是自己真的想做的事,甚至習慣於這類利益收穫而迷失自我呢?


船長啊,真的是不可強求的。目前讓我想到的是碩班老闆,每次個人 meeting 後,談完都會莫名地被打氣一般,或許這就是一種霸氣吧!出社會後,反而比較常看到別人如何推拖、選擇,鮮少那種彼此鼓舞的場景,剩下的大概是八卦的分享或是洗腦吧 XD


草帽海賊團,成員彼此的目標不同,但如果能找到一種方式共同付出與收成,那就真的是太棒了,碰到的話,真的要珍惜。



Android 開發筆記 - 使用 Facebook SDK

android-fb


在 Android 上使用 Facebook SDK 比在 iOS 上麻煩了一點,也算是安全性在高了一點點。


相關資料:



細節:


所有操作流程可以在 Facebok Developer - Mobile Apps 找到。發布 Android apk 時,將拿著一把鑰匙進行簽名的動作,因此在 Facebook Developer 頁面上,可以填寫用哪一把 key 作簽名,代表只有使用此把 key 簽名的 app 才能使用你的 Facebook api key 進行存取。


例如 OAuth 的使用是要有一對 key-pair 的,使用時一把擺在 server site ,另一把擺在 client 端使用,但要用在 Mobile 端時就會很不安全,因為兩把 key 都會寫在 app 裡,變相就是都存在 client 端。以 iOS 來說,雖然編譯的成果是 binary 檔案,但用特殊工具還是可以設法找到字串,不一會兒兩把 key 就被拿到了!至於Android 上可以參考 Android 開發教學筆記 - 關於反組譯 Android 程式,還真的不用 30 秒就搞定!只需幾個步驟就把 apk 檔打開將程式碼看個清楚了,更別說兩把 key 在哪 XD


在 Facebook 上頭,對 Android 來說,需使用簽署 apk 的資訊跟 Facebook api key 共兩個資訊,在 iOS 則是使用 Facebook api key 而已。在 app 裡存放 facebook api key 的缺點是存在被別人盜用的機會,所以在 Android 上算是相對安全一點點點點,因為還包含簽署的 apk 資訊。


所需的軟體:



流程:


開啟 Eclipse 後,先把下載的 facebook-android-sdk 匯入


[File] -> [New] -> [Projeect] -> [Android Project] -> Create project from existing source ,此例是  C:\facebook-facebook-android-sdk-5d44d0c\facebook ,並按 Finish 結束


facebok_sdk_lib


建立 FB Test Project,版本應該可以隨意,在此使用 Android 2.2 版:


fb_test


並且設定編譯時使用 facebook-android-sdk:


點選 Project 後,選 [Project] -> [Properties] -> [Android] -> [Library] -> 透過 Add 新增 com_facebook_android


com_facebook_sdk


撰寫相關測試的程式碼:


package com.test.fb;

import android.app.Activity;
import android.os.Bundle;
import com.facebook.android.*;
import com.facebook.android.Facebook.*;


public class FB extends Activity {
    private Facebook facebook = new Facebook("Your_Facebook_API_Key");
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        facebook.authorize( this, new DialogListener(){
@Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
}
@Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
}
@Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
@Override
public void onCancel() {
// TODO Auto-generated method stub
}
        });

    }
}


設定 AndroidManifest.xml 新增 android.permission.INTERNET 權限:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test.fb"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".FB"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>


上述就是程式碼的設定部分,只是編譯完跑在模擬器上,只會顯示一下下 Loading 的頁面,就結束了,主因是還未設定對應的 key:


facebook_test_not_ready


接著進行設定 Facebook API Key 的使用,須到 Facebook Developer 頁面上,對你自己新增的 Facebook App 新增 Android Hash Key:


facebook_key_hash


至於新增 Android Hash Key 的方式,主要參考簽署 apk 所用的 key ,假設沒有特別設定,那預設數值可以在 Eclipse -> [Windpw] -> [Preferences] -> [Build] 查看到 Default debug keystore 資訊,預設是在 C:\Users\id\.android\debug.keystore 位置 (Win 7) ,並且在 Signing Your Applications | Android Developers 可得知預設的資訊:


Keystore name: "debug.keystore"
Keystore password: "android"
Key alias: "androiddebugkey"
Key password: "android"
CN: "CN=Android Debug,O=Android,C=US"


所以,接著須要使用 kyetool 和 openssl 來建立 Android Hash Key 啦,我把 openssl 解壓縮在 C:\openssl\bin\openssl.exe 裡頭,連續動作:


"C:\Program Files\Java\jdk1.6.0_25\bin\keytool.exe" -exportcert -alias androiddebugkey -keystore C:\Users\id\.android\debug.keystore | | C:\openssl\bin\openssl.exe sha1 -binary | C:\openssl\bin\openssl.exe base64


輸入 keystore 密碼:android


就會產生一組 Android Hash Key,例如 dsfDFjakldEajdlfad+ha783j4g= 這種訊息,把它填入 Facebook App 之 Android Hash Key 欄位即可。


補充一下,如果你使用的 keystore 是自己產生的,那請自行更改對應的位置,以及使用 Custom debug keystore 吧( Eclipse -> [Windpw] -> [Preferences] -> [Build] ),不然就是建立 Android apk 時,改成手動簽名,相關資訊:


建立自己的 apk-key:


"C:\Program Files\Java\jdk1.6.0_25\bin\keytool.exe" -genkey -v -keystore C:\Path\your-apk-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000


並填寫相關資訊


手動 apk 簽名:


"C:\Program Files\Java\jdk1.6.0_25\bin\jarsigner.exe" -verbose -keystore C:\Path\your-apk-key.keystore C:\Users\id\workspace\YourProject\bin\YourProject.apk your_alias_name


手動安裝 apk:


"C:\Program Files (x86)\Android\android-sdk\platform-tools" install C:\Users\id\workspace\YourProject\bin\YourProject.apk


若軟體已存在,則使用 -r 指令重裝:


"C:\Program Files (x86)\Android\android-sdk\platform-tools" install -r C:\Users\id\workspace\YourProject\bin\YourProject.apk


最後,如果運行的結果還是沒有呈現出來,請參考 Android 開發教學筆記 - 模擬器無法建立網路連線 這篇,去新增 dns-server 資訊。可以在 onError 裡,使用 TextView 把錯誤訊息印出來:


com.facebook.android.DialogError: The Connection to the server was unsuccessful.


fb test error


Android 開發筆記 - 模擬器無法建立網路連線

android no network


在測試 Facebook Android SDK 時,發現程式無法建立網路連線,接著用 Browser 嘗試網路連線,才發現連 Browser 也連不出去。


網路上找一下資訊,一種是在模擬器視窗上按 F8 (Windows平台),即可啟動網路連線,這時候右上方會顯示 3G 圖示:


android 3g


但是,有時還是無法連上網,這時候就可以設定模擬器的 DNS 資訊:


[Run] -> [Run Configurations] -> [Android Application] -> [Your Project Name] -> [Target]


Additional Emulator Command Line Options 填寫 -dns-server 8.8.8.8,8.8.4.4 即可


android add dns


調完記得把模擬器關掉再重跑,就可以連上網路:


android 3g testing


2011年5月27日 星期五

[Linux] VNC + SSH Tunnel + iptables @ Ubuntu 10.04 desktop

由於要上課的關係且手邊的筆電只有 EEE PC 等級,課程卻是要開 Eclipse 跑 Android 模擬器,故選用了遠端桌面啦,但 Ubuntu 的遠端桌面不太好用?!不曉得可能是因為我不太懂,每次啟動 VNC 時,除了本機端不能 logout 外,且 VNC 好像也不是加密連線?


簡單的說,當 Ubuntu desktop 要開啟遠端連線時,遠端看到的畫面就目前本機端看到的,所以不能 logout ,因為 logout 的話,遠端也是看到一樣的畫面 XD 我記得 Ubuntu 裡頭有 "遠端桌面" 跟 "遠端登入",我猜我可能有些誤解,印象中以前有用過遠端登入使用 X-Window 的說。


至於在 Ubuntu 上使用遠端桌面且希望加密的解法,就是使用 SSH Tunnel ,讓所有連線內容都走 SSH 加密連線。而 iptables 是 Ubuntu 的防火牆設定,把 VNC 的預設 5900 port 限制一下,僅限本地端連線,這樣算是基本的安全設定吧。


環境敘述:


一台 Ubuntu 10.04 desktop 工作機、一台 Windows XP 小筆電


Ubuntu:


vnc_remote_desktop



  • 開啟 SSH 服務提供遠端登入

    • $ sudo apt-get install openssh-server



  • 開啟 VNC 服務,並限定需要密碼才能登入

    • [System] -> [Preferences] -> [Remote Desktop]



  • 設定 iptable ,限制只能本地端 localhost 登入 5900 port (VNC port),對外網卡是 eth0

    • $ sudo iptables -A INPUT -i eth0 -p tcp --dport 5900 -j DROP




Windows XP:


ssh_tunnel



  • 使用 PuTTY 建立 SSH Tunnels,讓本地端 localhost 5900 對應到 Ubuntu 機器的 5900 


    • PuTTY -> Connection -> SSH -> Tunnels -> Source Port (5900) 、Destination(ubuntu_ip:5900) ,按 Add 新增,之後就可以點 Open 開啟連線



  • 使用 RealVNC - VNC® remote control softwareVNC Viewer Free 軟體進行遠端登入,免費的,下載軟體時可以不填資料

    • 連線位置 localhost 即可,過程會需要輸入 Ubuntu 設定的遠端桌面的密碼




使用的感覺是堪用,如果在 VNC Viewer 進行登出、鎖定螢幕等動作,會導致無法連回 Ubuntu 機器。最大的缺點是... Ubuntu 本機端無法 lock screen 會有資安問題!


2011年5月26日 星期四

[Unix] awk: Too many open files @ FreeBSD

之前用 awk 練習,[Unix] 簡易分析 Squid 產生的 log @ FreeBSD,結果最近跑的時候開始碰到這個問題:Too many open files,一時之間還以為是自己程式的 bug,最後發現是 awk 裡有用到 pipe 等相關開檔動作,做完要記得 close 就行了。


簡易範例:


awk  ' { data[$1]++ } END { for( d in data ) { cmd = "wc -l /tmp/file";  cmd | getline result ;  close( cmd );   print result;   }   }'


由於是跑迴圈,資料多筆時就會碰到 Too many open files 的問題,只要把每個 pipe 或 file 相關的動作都有 close 掉就能解決囉。


2011年5月23日 星期一

[Linux] Building Pidgin 2.7.11 & MSN MPOP Problem @ Ubuntu 10.04

即時通(IM)軟體,已經成為 RD 人員對內或對外的溝通管道,在 Ubuntu 環境上,有幾種可以選擇,我選擇使用 Pidgin (鴿子圖)軟體,Open source 的,目前 Ubuntu 10.04 Desktop 64bit 環境中,可以用軟體管理安裝 Pidgin 2.6.6 版本。此 Pidgin 支援眾多 IM 服務,如 MSN、GTalk、QQ、ICQ 等,另外在 Mac OSX 的 Adium (鴨子圖)軟體也採用 Pidgin 核心


至於為啥要安裝最新版?去年底有一陣子使用 MSN 時,會有 CA 憑證問題,當時使用新版可以解決,最近則是看到 Adium 1.5hg 版可以支援多重地點上線(例如 WinXP 與 Ubuntu 同時使用同一個帳號上線),在加上他的核心是 Pidgin,所以就想來編看看新版,目前使用 Pidgin 2.6.6 版時,不支援多重地點上線。


安裝環境:


Ubuntu 10.04.2 Desktop 64-bit @ 2011-05-23 & VirtualBox


$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo reboot


相關環境:


$ sudo apt-get install intltool libgtk2.0-dev libxss-dev libgtkspell-dev libxml2-dev libgstreamer0.10-dev libgstfarsight0.10-dev libgstreamermm-0.10-dev libidn11-dev libmeanwhile-dev libavahi-core-dev libavahi-client-dev libavahi-glib-dev libdbus-glib-1-dev libnm-glib-dev libperl-dev libgnutls-dev tcl8.4-dev tk-dev


編譯(Pidgin 原始碼 http://pidgin.im/download/source/):


$ wget "http://downloads.sourceforge.net/project/pidgin/Pidgin/2.7.11/pidgin-2.7.11.tar.bz2?r=http%3A%2F%2Fpidgin.im%2Fdownload%2Fsource%2F&ts=1306119851&use_mirror=nchc" -O pidgin-2.7.11.tar.bz2
$ tar -xvf pidgin-2.7.11.tar.bz2
$ cd pidgin-2.7.11
$ ./configure
$ sudo make install clean


重開機(登入?)以後,就可以在 Internet 那邊看到 Pidgin 軟體。 


其他編譯時會碰到訊息(已安裝相關環境則不會碰到):


configure: error:  (libxss-dev)
XScreenSaver extension development headers not found.
Use --disable-screensaver if you do not need XScreenSaver extension support,
this is required for detecting idle time by mouse and keyboard usage.

configure: error: (libgtkspell-dev libxml2-dev)
GtkSpell development headers not found.
Use --disable-gtkspell if you do not need it.

configure: error: (libgstreamer0.10-dev)
GStreamer development headers not found.
Use --disable-gstreamer if you do not need GStreamer (sound) support.

configure: error: (libgstreamermm-0.10-dev libgstfarsight0.10-dev)
Dependencies for voice/video were not met.
Install the necessary gstreamer and farsight packages first.
Or use --disable-vv if you do not need voice/video support.

configure: error: (libidn11-dev)
GNU Libidn development header not found.
Use --disable-idn if you do not need it.

configure: error: (libmeanwhile-dev)
Meanwhile development headers not found.
Use --disable-meanwhile if you do not need meanwhile (Sametime) support.

configure: error:  (libavahi-core-dev libavahi-client-dev libavahi-glib-dev)
avahi development headers not found.
Use --disable-avahi if you do not need avahi (Bonjour) support.

configure: error:  (libdbus-glib-1-dev)
D-Bus development headers not found.
Use --disable-dbus if you do not need D-Bus support.

configure: error:  (libnm-glib-dev)
NetworkManager development header not found.
Use --disable-nm if you do not need D-Bus support.

configure: error:  (libperl-dev)
Perl development headers not found.
Use --disable-perl if you do not need Perl scripting support.

configure: error:  (libgnutls-dev)
Neither GnuTLS or NSS SSL development headers not found.
Use --disable-nss --disable-gnutls if you do not need SSL support.
MSN, Yahoo!, Novell Groupwise and Google Talk will not work without SSL. OpenSSL is NOT usable!

configure: error:  (tcl8.4-dev)
Tcl development headers not found.
Use --disable-tcl if you do not need Tcl scripting support.

configure: error:  (tk-dev)
TK development headers not found.
Use --disable-tk if you do not need Tk scripting support.


關於 Multiple Points of Presence (MPOP):


去年 11 月底,有碰到一陣子 MSN CA 憑證問題,當時有看到一些文章在講 Pidgin 2.7.6 除了解決此問題外,也支援 MSNP16 及 MPOP 功能,而甚麼是 MPOP 功能呢?就是支援同一帳號多處上線的功能。


相關文件:


Microsoft_Notification_Protocol#MSNP16


Ticket #8247 (closed enhancement: fixed) - Support MSNP16 multiple logins


Pidgin News @ November 01, 2010 - MSNP16 and SLP-rewrite merged


隨後我也翻了一下 Pidgin-2.7.11 的程式碼,發現的確有對應的程式,但不知為啥我在使用 Pidgin-2.7.11 時,在設定帳號那邊,卻找不到相對應設定 MPOP 的選項?後來發現,如果是使用 /usr/local/bin/pidgin 就不會看到,但用 src 裡 pidgin/pidgin 執行,就可以看到設定選項多了 Allow connecting from multiple locations 啦!


mpop


如果把 mpop 關掉,則是在 ~/.purple/account.xml 裡 <settings> 中會多一欄(預設並不會設定此直,可能預設就是啟用 MPOP 模式):


<setting name='mpop' type='bool'>0</setting>


那如果看不到此 UI 的話,強制去更新 account.xml 加上 <setting name='mpop' type='bool'>1</setting> 好像可強制啟用 MPOP 吧?但測試的結果,無論打開選項或關掉都沒有影響。感覺此功能好像是被隱藏起來,不然就是有使用條件的限制。


另外一提,Ubuntu 10.04 內建環境的 Pidgin-2.6.6 哩,是使用 libpurple 2.6.6 ,但我安裝新版的 Pidgin-2.7.11 哩,在"說明"中還是用 libpurple 2.6.6 而已。簡單的說,我覺得內建環境的 Pidgin-2.6.6 應該就可以使用 MPOP 才對 :P 因為函式庫是同版本。我想我應該有遺漏甚麼,有空再來查查。


2011年5月20日 星期五

美麗的誤會

排氣檢查的禮物


又到了一年一度的排氣檢查,我那台老車啊,想說去年從宿舍騎沒 3 分鐘就去測試,結果當然是失敗 XD 這次我記取教訓,乾脆騎到市區順便領火車票,在途中看到一間有檢測的店就給他測了一下,結果...還是沒過 XD


這是測試的是 A 老闆,A 老闆看到測沒通過時,很好意地跟我說,請我去我信任的車行維修,這句話給人感覺很讚,不像去年第一次測的 C 老闆,一臉奸笑著說要收多少錢 XD 隨後我就去找 B 老闆維修,而 B 老闆是大家掛保證的好老闆,去年也是找他維修的,只可惜 B 老闆沒再做檢測。讓他幫我調整了一會後,由於今年的排氣測試維修還要簽名,所以 B 老闆覺得如果沒測過還要再維修,要不斷地從 A 到 B 跑來跑去,對我有點不方便,在加上看到檢測的是 A 老闆,馬上就跟我說 A 老闆人很老實,請我放心地給他維修就好,這樣要測試也比較方便。


所以,我就多認識一位好機車老闆(怪怪的稱呼XD)。在維修的過程,我擔心口袋不夠深,所以會多詢問幾次價錢,並且維修過程,其徒弟還會詢問某個舊東西要不要換,結果 A 老闆回說還可以用,就繼續用,整個維修過程讓我感到很安心 :) 最後的測試當然就是 Pass 啦!只是 A 老闆還是跟我提醒,二行車對環境本來就比較有汙染,現在檢測成功,比較像吃安非他命罷了,建議還是考慮換一下車,對環境比較好,好感再次 ++ 


我覺得與人相處就是要互動,修車的過程我嘗試詢問對方可能擅長的回答內容,例如培養一位師傅要花幾年等等,讓老闆講得很順嘴,漸漸地就會像聊天了 :D 老闆還跟我說,像我剛剛第一次測時,旁邊也有一台進來,那台就是住在附近,騎來的車不夠熱的,他說這種他一定不測,要對方先騎去市區跑跑啦!這會讓我想起去年我車騎不夠久時(小於3分鐘吧),當時的 C 老闆還是執意幫我測,那種感覺是有落差的。


至於學徒方面,老闆說大概要花 3~5 年,我說不是有啥專科學校嗎,他說那邊教的是理論,到車廠上班就是學經驗,還說有些人看起來跳槽很多間,好似吸收很多經驗,但不見得是真本領。我想,言下之意就是找個好老闆,好好地跟一陣子,認真學習就對了。這讓我想到資訊業都沒有這種傳承的,如果老闆又不常 coding 的,大概只會丟幾篇 paper 或是要你看看哪些 framework 就拿來用,感覺真的有差啊 :P 在資訊業好像傳承的部分很少,大概都各憑本事吧。


除此之外,今天要去火車站時,等紅燈時還碰到一位咩問路 XD 可惜我回答得不出來,只說應該是在前面,雖然結果是猜對的,但還是挺遜的!我該多跑市區多記幾條路才是!


Anyway,有時也不用執著已知的解法,換個方向走走,也是挺不錯的,上圖就是測試成功後,老闆送我的禮物 XD 他說,要測試成功他才有錢可以領,也算是要謝謝我這個客人吧!(只是感覺很像去 xxx 後,付完錢,被對方包紅包 XD)


2011年5月18日 星期三

[Windows] 搭配 VirtualBox 共享目錄,使用 Dropbox 服務 @ Windows 7

今年開始用 Dropbox ,但由於資安安全性部分,我不太想直接在自己的電腦上直接安裝 Dropbox ,所以我想把 Dropbox 安裝在虛擬環境上(Guest OS),但資料又可以輕易的使用(Host OS),簡單來說讓資安問題停留在虛擬機器上,但實體機器又可以存取 Dropbox 之同步資料。


我使用的作業系統是 Windows 7 x64 ,原先在 Virtualbox 安裝一個 Windows XP 跑 Dropbox,透過 Virtualbox 共享資料夾(NFS),結果發現 Dropbox 不允許使用網路硬碟。這下可好了,想做的事都不能搞 XD 不使用網路硬碟算是有一些實作上的考量,例如 lock 的問題等。結果最近我安裝了 Ubuntu 來使用,想說再試一次網路硬碟的方式看看,沒想到在招在 Ubuntu 10.04 Desktop 64-bit 上適用耶!所以就來筆記一下。


Host:


OS:Windows 7 x64 + VirtualBox 4.0.4 r70112 (並非最新版,新版使用上有點問題,所以改換前一版)


使用目錄 D:\SharedDropbox


Guest:


OS:Ubuntu 10.04 Desktop 64-bit


dropbox


流程就很順地安裝完上述兩套環境,接著在 Guest OS 上安裝 Virtualbox Guest Additions ,並共享 Host 端 D:\SharedDropbox 目錄,勾選 "自動掛載" 和 "永久性",使用的名稱還是 SharedDropbox。接著在 Ubuntu 環境上(Guest OS)進行自動掛載的設定:


$ sudo mkdir /SharedDropbox
$ sudo vim /etc/fstab


# /etc/fstab: static file system information.
#
# Use 'blkid -o value -s UUID' to print the universally unique identifier
# for a device; this may be used with UUID= as a more robust way to name
# devices that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
proc            /proc           proc    nodev,noexec,nosuid 0       0
# / was on /dev/sda1 during installation
UUID=#####-####-####-####-###### /               ext4    errors=remount-ro 0       1
# swap was on /dev/sda5 during installation
UUID=########-####-####-####-######## none            swap    sw              0       0
# Dropbox
SharedDropbox   /SharedDropbox  vboxsf  defaults        0       0


重點是上述最後兩行。


$ sudo reboot


上述重開機完就算完成,以後Ubuntu 開機時就會自動掛載該目錄。如果只想要測試,就先用 sudo mount -t vboxsf ShadredDropbox /SharedDropbox 看看,例如在該目錄建立一個檔案,是否能在 Windows (Host OS)上看到。


最後就能用叫 Ubuntu 幫你抓好資料擺好,然後用 Windows 存取那些檔案啦,有點脫褲字放屁啦 XD


2011年5月17日 星期二

學而不用則荒廢、不學東西則懶散

20110509-sunny


趁著天氣好時,拍一張,有時並不是天天都有好風景,但換個角度仍是又一村啊。


子曰:「學而不思則罔,思而不學則殆。」身在一處專碰新技術的單位,這半年開始會有這樣的念頭。天天有機會接觸新的東西,但總是沒那個展現環境,派不上用場,時常觀察新趨勢,左看看右看看,手上的成品卻不曾一點茁壯。之前也寫過一篇心得:戒了 iPhone、iPod touch 和 iPad 產品,深深覺得真正有價值的不是多酷炫的 UI 、高效率的程式,而是使用者當下情愫下,生產出來的內容。然而,就該因為這些停步嗎?我想這又有點本末倒置了,這之中必須尋求一個平衡點。


趁著今天的萬安演習,跟隔壁 team 的同事閒聊幾句,我問他是否念博班,他跟我說他喜歡寫 code 所以很明確現在不想追求學問。幾天前跟幾位大學同學閒聊,發現不少人擁有高薪生活,但工作內並非寫程式。


打算少用 Social Network Service 好了,最近覺得 Social Network 只是另類的孤獨方式,看起來好像很快樂,實際上卻甚麼也沒留下。專心一下,產生一些足跡吧!


2011年5月16日 星期一

[PHP] 使用 cURL POST 上傳檔案

好久沒寫 PHP 了,連自己工作的機器上都忘了安裝 orz 這半年一直都在寫 python 啊,這次使用 PHP 來模擬短時間的大量連線。


在 Ubuntu 的安裝:


$ sudo apt-get install php5-cli php5-curl


之前只有透過 curl 使用 POST 送出 text 類的資料,這次想要模擬檔案上傳,一開始使用:


$POST_DATA = array( 'my_file' => file_get_contents( '/path/my_file' ) );


但還是送不出去,最後才發現要用:


$POST_DATA = array( 'my_file' => '@/path/my_file' );


大概是這樣才會被轉換使用 multipart/form-data 的方式,完整範例:


<?php

        $url = 'http://host/upload';

        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $url );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_POST, true );
        curl_setopt( $ch, CURLOPT_POSTFIELDS, 
array(
               //'my_file' => file_get_contents( '/path/my_file_data' ) 
               'my_file' => '@/path/my_file_data' 
)
);  
        echo curl_exec( $ch );
        curl_close( $ch );
?>


2011年5月15日 星期日

[C] C 語言,使用 Perl Compatible Regular Expressions (PCRE)

幾年前也寫過一篇:[C] C 語言,使用 Regular Expressions,那時是使用 Regex library 也曾說過要用看看 PCRE 啦,結果日子久了就都忘光光,倒是前陣子在 visual studio 編譯 c++ project 時,發現怎都忘光光 Orz 所以來寫一篇筆記吧。


至於 PCRE 的好處嘛,如果常開發 PHP 並使用 preg_match 或 preg_match_all 等相關函式庫的話,那使用的語法一致的啦。


簡單的 main.c 範例:


#include <pcre.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main( int argc, char ** argv)
{
        pcre *re;
        const char *error;
        int erroffset;
        int ovector[30];
        int options = 0;

        if( argc < 3 )
        {
                printf("Usage> %s \"PCRE_PATTERN\" \"TEST_DATA\"\n", argv[0]);
                return 0;
        }
        if( ( re = pcre_compile( argv[1], options, &error, &erroffset, NULL) ) == NULL )
        {
                fprintf(stderr, "PCRE compilation failed at offset %d: %s\n", erroffset, error);
                exit(1);
        }
        if( pcre_exec(re, NULL, argv[2], strlen(argv[2]), 0, 0, ovector, 30) >= 0 )
                printf("Match\n");
        else   
                printf("Not Found\n");
        return 0;
}


在 FreeBSD 編譯:


如果系統已經安裝過 pcre 相關 lib 的話,僅需編譯程式時,指定函式庫相關資訊即可


> gcc -I/usr/local/include -L/usr/local/lib -lpcre main.c


如果沒有安裝過,那只好去 PCRE - Perl Compatible Regular Expressions 官方網站下載原始碼來編譯一下。


> cd pcre_test
pcre_test> wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.12.tar.gz
pcre_test> tar -xvf pcre-8.12.tar.gz && cd pcre-8.12
pcre_test/pcre-8.12> cd pcre-8.12
pcre_test/pcre-8.12> ./configure && make && cd ..
pcre_test> ls
main.c          pcre-8.12/        pcre-8.12.tar.gz


pcre_test> gcc -DHAVE_CONFIG_H -DPCRE_STATIC -Ipcre-8.12 pcre-8.12/pcre_chartables.c pcre-8.12/pcre_compile.c pcre-8.12/pcre_config.c pcre-8.12/pcre_dfa_exec.c pcre-8.12/pcre_exec.c pcre-8.12/pcre_fullinfo.c pcre-8.12/pcre_get.c pcre-8.12/pcre_globals.c pcre-8.12/pcre_info.c pcre-8.12/pcre_maketables.c pcre-8.12/pcre_newline.c pcre-8.12/pcre_ord2utf8.c pcre-8.12/pcre_refcount.c pcre-8.12/pcre_study.c pcre-8.12/pcre_tables.c pcre-8.12/pcre_try_flipped.c pcre-8.12/pcre_ucd.c pcre-8.12/pcre_valid_utf8.c pcre-8.12/pcre_xclass.c pcre-8.12/pcre_version.c pcre-8.12/pcreposix.c main.c



pcre_test> gcc -Ipcre-8.12 main.c pcre-8.12/.libs/libpcre.a


pcre_test> ls
a.out*            main.c          pcre-8.12/        pcre-8.12.tar.gz


測試:


pcre_test> ./a.out 
Usage> ./a.out "PCRE_PATTERN" "TEST_DATA"
pcre_test> ./a.out "<a></a>" "<a>test</a>"
Not Found
pcre_test> ./a.out "<a>(.*?)</a>" "<a></a>"
Match


在 VC++ 編譯:


PCRE 內附 cmake 編譯方式,正統的方式應該是透過 cmake 編譯出 lib 來使用,在這邊就手動調調,直接用 src 把玩一下。


建立 2 個 projects,其中一個是 libpcre 另一個則是 main,前者是 PCRE 的相關資料,後者是上述的 main.c 例子。對 libpcre 來說,先把壓縮檔內 config.h.generic、pcre.h.generic 和 pcre_chartables.c.dist,分別複製成一份 config.h、pcre.h 和 pcre_chartables.c。


source, header


接著設定兩個 projects 的 properties 等,對 libpcre 和 main 兩者來說:


[C/C++] -> [General] -> [Additional Include Directories] 加入 pcre-8.12 的目錄位置


[C/C++] -> [Code Generation] -> [Runtime Library] 設定為 Multi-threaded (/MT) ,理由是我要用 static 的,並且不想使用 DLL ,這樣才比較 portable 。


multi-threaded


對 libpcre 個別設定:


[General] -> [Configuration Type] 設定為 Static library (.lib)


[C/C++] -> [Preprocessor] -> [Preprocessor Definitions] 加 HAVE_CONFIG_H;PCRE_STATIC; 


對 main 個別設定:


[Common Properties] -> [Framework and References] -> [Add New Reference],請加入 libpcre


[C/C++] -> [Preprocessor] -> [Preprocessor Definitions] 加 PCRE_STATIC; 即可


[Project Dependencies],對 main Projects 請勾選 libpcre ,這樣編譯過程會先編 libpcre


dependencise


如此一來就能夠 build 出來啦


其他筆記:


如果編譯過程中會有 error LNK2001: unresolved external symbol __pcre_default_tables 的話,那應該是 libpcre 編譯過程中少了 pcre_chartables.c 檔案,可以從 pcre_chartables.c.dist 複製出來;若是 error LNK2019: unresolved external symbol __imp__pcre_exec referenced in function _main 這類的,那應該是 main project 之 preprocessor definitions 忘了加 PCRE_STATIC  或是 Framework and References 要加一下 libpcre 囉


2011年5月11日 星期三

專利啊

有幸參與公司專利的提案,透過長輩的指導,讓我對專利有初步的了解。青蛙希望可以分享一下下,在此就稍微筆記一下心得,細節還需多多參與專利課程才能補齊。


由於我並沒有參與專利課程,所以對於專利的觀念應該很不完整,僅供參考。



  1. 專利最初的目的是用來保護自己的發明

  2. 專利可以分成發明、再發明和新樣式,三種型態

  3. 提出的專利,必須不能被其他專利、論文所揭露過的概念(須調查各國專利或請事務所專利工程師協助)

  4. 假設 A 專利的元素是 a, b, c 三種元素,而 B 專利是 a, b, d 元素,那 B 專利還是可以申請;假設 C 專利是用 a, b, c, e 的話,還是可以申請,但行使時,必須有 A 的專利授權 

  5. 申請專利不難,僅需把專利範圍寫好不要踏到別人的專利,最大的負擔是申請過程和費用

  6. 申請專利和維護是需要費用的,在公司發專利就是公司出錢,因此也會有嚴格的審核過程,例如考慮專利的價值,而發明人與公司存在一種利益比例

  7. 專利範圍越大對公司越有價值,代表別人容易踏到你的專利,但已有跳脫(1)的本意,因為一些發明通常是從小地方萌芽,例如最初研發是要給小孩的踏步車,成果卻想把範圍寫到機車、汽車甚至飛機也被包含等

  8. 演算法類的專利比較好申請,但抓不到(無價值?又把方法告訴別人);偏 UI、系統類的專利比較好抓,但不太好申請(審核時容易被模糊焦點,或是說 ooo 也有類似的功能)

  9. 專利是有國家限定的,例如在美國申請專利通過,該專利就僅限於美國。所以才有 A 公司拿著美國專利告 H 公司,想要限制 H 公司不能在美國販賣商品

  10. 專利是可以被推翻的。除此之外,假設在同一個專利在美國、台灣都有,但美國專利被推翻時,將導致敵手拿著美國專利無效的結果,要求台灣專利也無效

  11. 專利的發明人千萬不要給別人掛名,因為推翻專利最簡單的方式就是找其中之一的發明人詢問,若對方答不出來容易被判斷成無效專利

  12. 專利是法律文件,重邏輯性,因此不好閱讀或撰寫


申請專利前,還是多想想 (1) 吧!不然蔓延下去就快跟嘴砲沒兩樣。開發系統時,若牽扯到授權販賣給廠商時,容易被詢問是否有專利,這是廠商用來保護自己的。如果不想申請專利保護自己,又不想被別人專利,那就可以發 paper 揭露想法,或是一些公開處加以發布想法。除此之外,別人說有專利,那還得看看專利是否有效,通過的專利是一回事,無效的專利又是另一回事。


最後,專利看多時,會發現一些很基本的概念竟然都被申請專利了,不就代表別人可以拿著專利告你嗎?只是提告時會需要證據,大概是蒐證的難易問題。其次,專利感覺還是有錢人在玩的遊戲 XD 因為申請要錢,維護也要錢啊,會覺得:


專利是拿來保護發明人;專利是有錢人才玩得起的;這樣是否代表專利是用來保護有錢人繼續有錢呢?


2011年5月6日 星期五

[Android] Android Market and AOSP @ Nexus One、Android 2.3.3

android_market01 android_market02


之前嘗試編譯 AOSP 後,發現編譯後裡頭很乾淨,連 Android Market 都沒有,頓時不知道該怎樣安裝軟體,變成安裝軟體必須找到 apk 檔案,並且使用 adb install *.apk 或 adb push *.apk /system/app 的方式安裝,十分不方便,我有嘗試從 Apps - Android Market 網頁安裝,但都沒反應?!所以就著手研究在 AOSP 上安裝 Android Market 的嘗試,倒是看了不少文章都說 AOSP 預設是不會包含任何 Google app 的,可能是 License 問題或是 Google 並沒有 Open source 的關係,總之找到的解法要嘛就是去跟 Google 要(?),不然就是安裝網路上可以找到的 android market.apk 檔案,只是 android market 使用上會需要綁帳號的,對於別人做的東西還是要三分保留啊,以免帳密被第三方取得!總之,我就東看看西摸摸,搞懂了一些東西,決定從原先 Android 2.3.3 中取得相關 Android market 程式,拼拼湊湊弄出功能囉。


首先,從 Nexus One with Android 2.3.3 裡,在 /system/app 裡撈出 Android Market app,但找了很久都沒看到!最後才知道,這個 Android market app 是叫作 Vending.apk 啦,但是擺進 AOSP 裡後,卻看不到 Android Market 耶?找了一些文章,才知道 Nexus One 裡的 Google app 都有兩種東西: apk 跟 odex 檔案,兩者要搭配在一起才能使用,但我把兩者透過 adb push 到 AOSP 裡也依舊看不到,所以就改從事反組譯類的工作 XD 


把玩"魔術師" -- 認識、把玩 APK 檔 這篇文章中,得知 odex 是最佳化後的產物並且搭配 apk 使用的,如果要整合成使用單一 apk 檔,就必須整 odex 資訊整合回 apk 啦。多虧這篇文章,我又認識 dsixda Android Kitchen。簡單來說,這是一個製作客製化 ROM 的整合工具,包括建立 ROM 啊、重新 sign apk 等,我只需要的是將 odex 整進 apk 檔案,這些東西是分類在 decode 部分。


參考 Android Kitchen 之 decode 後,得知負責 decode 的也有 open source:smali - An assembler/disassembler for Android's dex format,而取得 smali.jar baksmali.jar 後,就能工作啦!


總結流程:



  1. 從 Nexus One with Android 2.3.3 官方環境中,取得 Android Market 及其相關函式庫(主要是 Vending 跟 GoogleServicesFramework)


    • $ adb pull /system/app /tmp

    • $ adb pull /system/framework /tmp

      • 這不見得需要,因為我後來在 decode 的過程中並沒使用 XD





  2. 使用 smali 將 odex 整進 apk 中

    • 將 Vending.odex 併入 Vending.apk

    • 將 GoogleServicesFramework.odex 併入 GoogleServicesFramework.apk

    • 連續動作,假設 Vending 跟 GoogleServiceFramework 都擺在 app 中:

      • $ ls
        app  baksmali-1.2.6.jar  framework  smali-1.2.6.jar

        $ ls app
        GoogleServicesFramework.apk  GoogleServicesFramework.odex  Vending.apk  Vending.odex

        $ java -Xmx512m -jar baksmali-1.2.6.jar -d framework/ -x app/Vending.odex
        $ java -Xmx512m -jar smali-1.2.6.jar -o classes.dex out           
        $ zip -r -q app/Vending.apk classes.dex
        $ rm -rf out/ classes.dex

        $ java -Xmx512m -jar baksmali-1.2.6.jar -d framework/ -x app/GoogleServicesFramework.odex
        $ java -Xmx512m -jar smali-1.2.6.jar -o classes.dex out
        $ zip -r -q app/GoogleServicesFramework.apk classes.dex
        $ rm -rf out classes.dex






  3. 將整合好的 Android Market 及相關函式庫擺進 AOSP 裡

    • 使用 adb install

      • $ adb install Vending.apk 
        1172 KB/s (1091549 bytes in 0.909s)
                pkg: /data/local/tmp/Vending.apk
        Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]

      • 算是預期中的結果 XD 解法應該是重新 sign apk

        • $ java -jar signapk_files/signapk.jar signapk_files/testkey.x509.pem signapk_files/testkey.pk8 GoogleServicesFramework.apk GoogleServicesFramework-signed.apk
          $ java -jar signapk_files/signapk.jar signapk_files/testkey.x509.pem signapk_files/testkey.pk8 Vending.apk Vending-signed.apk
          $ adb install GoogleServicesFramework-signed.apk
          1196 KB/s (1123115 bytes in 0.917s)
          pkg: /data/local/tmp/GoogleServicesFramework-signed.apk
          Success
          $ adb insatll Vending-signed.apk
          1221 KB/s (1089904 bytes in 0.871s)
          pkg: /data/local/tmp/Vending-signed.apk
          Success

        • 但開始使用時,卻發現無法登入 Google,猜想應該是重新 sign apk 的影響,所以就改用 adb push 啦





    • 使用 adb push

      • $ adb root
        restarting adbd as root
        $ adb remount
        remount succeeded
        $ adb push Vending.apk /system/app
        1150 KB/s (1091549 bytes in 0.926s)
        $ adb push GoogleServicesFramework.apk /system/app






收工!接著就可以從 AOSP 啟用 Android Market 囉!一開始執行會看到一個 alert 錯誤視窗,但流程接著是選擇網路、指定 Google Account 後,重新啟動 market 後是正常了,嘗試安裝一下 Angry Birds,跑起來沒啥問題,應該是搞定啦。


android_market03 android_market04 android_market05 android_market_2.13


目前的 Android Market 是 2.13 版,網路上倒可以找到 2.2.11 版的,但我沒啥需求,先用這就好 :D 這篇主要是學到整合 odex 跟 apk 的方式囉,接下來就可以專心改改 AOSP 啦!


2011年5月1日 星期日

大陸劇 胡雪巖

49


同事常跟我提起,他覺得能夠和伴侶逛逛賣場,是件很幸福的事,我也這麼覺得,每次到台北閒逛時,也會到賣場走走,總是會留念一下那便宜的影劇區。記得年初到訪時,還瞧見三姑六婆在那邊分享著,瞧著陌生的彼此用戲劇拉近距離,也怪好玩的。


胡雪巖


上一次我也差點敗了個三國演義呢,只不過這次瞧見 49 元一齣戲,一個便當錢就買了一部,哈。買了胡雪巖,剛剛用 Google 查了一下,某線上購物可要價個 99 呢。有時是種緣分,一回我在老鄉的流行唱片店也曾瞧見 199 的戲,一次買兩片可還能折個價呢!只是隨著年紀啊,花錢不是甚麼問題,倒是看戲的時間拿不出個丁點啊。


說說這齣戲,第一次看在碩班,有一位同學很愛從商之道,一開始還常約我去他家看影集,其中有一次就是這齣戲,可惜的我只瞧了一集,隨著當年的熱血 coding ,就不曾再看了。這次一連看了七集,發現感觸又不一樣了,還順手找了一下 wiki 呢,若還想看戲的就別看 wiki 吧 XD 因為我看了 wiki 就大概知道個劇情發展呢。


只是瞧著這古裝戲,總讓我想起古人的風華,好似妻妾成群抑或自如於商戰場等,總要找點事來磨揮磨揮,這可跟當今潮流,小三劇情,可有天差地別的走向 :P