2016年10月11日 星期二

如何解決eclipse無法在ubuntu 16.04上啟動

狀況:
ubuntu升級到16.04版之後,eclipse無法啟動,會一直卡在splash畫面。

解決方式:
問題應該是在16.04裡GTK+ 3的版本。

請先用下面步驟確認:
打開一個terminal視窗,然後輸入
export SWT_GTK3=0
然後在terminal視窗裡下命令啟動Eclipse.
如果這樣可以使得eclipse正常啟動。那請在eclipse.ini中加入下列2行敘述。

--launcher.GTK_version
2

請加在 --launcher.appendVmargs 前面。

相關的bug
Ubuntu bug 1552764

2016年5月30日 星期一

密碼學

最近在學習AllJoyn security 2.0,裏面有一些密碼學的東西,也順便一起看一下,有幾個不錯的概念網站,順便紀錄下來。


PK(金鑰加密系 統,Public Key Cryptosystems)的作用包括「資料保密」和「身份認證」兩方面。

當你需要寄送加密檔案給某人(假設為A君)時,需先向PK伺服器查詢A君的公 開金鑰,再以取得的公開金鑰進行資料加密。由於檔案是用A君的公開金鑰加密的,因此只有A君的私密金鑰才能解密。只要A君妥善保管好自己的私密金鑰,就能 確保檔案的隱密性。

至於身份確認方面,你需要事先透過適當的安全管道把代表自己身份的電子簽章檔送給A君,電子簽章檔可以是文字檔或簽名、印章的影像檔。 當你把利用A君公開金鑰加密的資料檔Email給對方時,可以附加上利用自己私密金鑰加密的電子簽章檔。

A君收到你寄送去的資料檔和電子簽章檔之後,可以使用他自己的私密金鑰對資料檔解密,同時向PK伺服器查詢你的公開金鑰,再利用取得的公開金鑰對電子簽章檔解密
比對解密後的電子簽章檔和你事先交付的電子簽章檔無誤之後,A君就能確認資料檔確實是你寄送給他的。

PK登記手續只需辦理一次,之後就可以透過網路隨時更換寄存在PK伺服器裡的 公開金鑰。使用者只要勤於更換公開金鑰和私密金鑰,甚至每一對公開金鑰和私密金鑰只用一次,用過即換,即可保障通訊內容安全無虞。


參考書目
Live-CA:結合 IC 卡的 PKI 憑證管理系統之設計與實現--國立高雄師範大學資訊教育研究所碩士論文

稻江科技暨管理學院提供的教學:密碼學原理與技術

Ivan Blog:何謂PKI?



2016年4月28日 星期四

[轉貼]用gcc 自製 Library

轉自 PTT LinuxDev


作者: cole945 (躂躂..) 看板: LinuxDev
標題: [心得] 用gcc 自製Library
時間: Sun Nov 5 04:15:45 2006


Library可分成三種,static、shared與dynamically loaded。


1. Static libraries
Static 程式庫用於靜態連結,簡單講是把一堆object檔用ar(archiver)包裝集合起來,檔名以`.a’ 結尾。優點是執行效能通常會比後兩者快,而且因為是靜態連結,所以不易發生執行時找不到library或版本錯置而無法執行的問題。缺點則是檔案較大,維護度較低;例如library如果發
現bug需要更新,那麼就必須重新連結執行檔。

1.1 編譯
編譯方式很簡單,先例用`-c’ 編出object 檔,再用ar 包起來即可。

____ hello.c ____
#include
void hello(){ printf(“Hello “); }

____ world.c ____
#include

void world(){ printf(“world.”); }

____ mylib.h ____
void hello();
void world();


$ gcc -c hello.c world.c /* 編出hello.o 與world.o */

$ ar rcs libmylib.a hello.o world.o /* 包成limylib.a */


這樣就可以建出一個檔名為libmylib.a 的檔。輸出的檔名其實沒有硬性規定,但如果想要配合gcc 的’-l’ 參數來連結,一定要以`lib’ 開頭,中間是你要的library名稱,然後緊接著`.a’ 結尾。


1.2 使用

____ main.c ____
#include “mylib.h”
int main() {
    hello();
    world();
}


使用上就像與一般的object 檔連結沒有差別。

$ gcc main.c libmylib.a

也可以配合gcc 的`-l’ 參數使用

$ gcc main.c -L. -lmylib

-L 參數用來指定要搜尋程式庫的目錄,`.’ 表示搜尋現在所在的目錄。通常預設會搜/usr/lib 或/lib 等目錄。
-l 參數用來指定要連結的程式庫,’mylib’ 表示要與mylib進行連結,他會搜尋library名稱前加`lib’後接`.a’的檔案來連結。

$ ./a.out
Hello world.



2. Shared libraries
Shared library 會在程式執行起始時才被自動載入。因為程式庫與執行檔是分離的,所以維護彈性較好。有兩點要注意,shared library是在程式起始時就要被載入,而不是執行中用到才載入,而且在連結階段需要有該程式庫才能進行連結。

首先有一些名詞要弄懂,soname、real name與linker name。

soname 用來表示是一個特定library 的名稱,像是libmylib.so.1 。前面以`lib’ 開頭,接著是該library 的名稱,然後是`.so’ ,接著是版號,用來表名他的介面;如果介面改變時,就會增加版號來維護相容度。
real name 是實際放有library程式的檔案名稱,後面會再加上minor 版號與release 版號,像是libmylib.so.1.0.0 。一般來說,版號的改變規則是(印象中在APress-Difinitive Guide to GCC中有提到,但目前手邊沒這本書),最尾碼的release版號用於程式內容的修正,介面完全沒有改變。中間的minor用於有新增加介面,但相舊介面沒改變,所以與舊版本相容。最前面的version版號用於原介面有移除或改變,與舊版不相容時。
linker name是用於連結時的名稱,是不含版號的soname ,如: libmylib.so。通常linker name與real name是用ln 指到對應的real name ,用來提供彈性與維護性。


2.1 編譯

shared library的製作過程較複雜。

$ gcc -c -fPIC hello.c world.c

編譯時要加上-fPIC 用來產生position-independent code。也可以用-fpic參數。(不太清楚差異,只知道-fPIC 較通用於不同平台,但產生的code較大,而且編譯速度較慢)。

$ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.0 hello.o world.o

-shared 表示要編譯成shared library
-Wl 用於參遞參數給linker,因此-soname與libmylib.so.1會被傳給linker處理。
-soname用來指名soname 為limylib.so.1
library會被輸出成libmylib.so.1.0.0 (也就是real name)

若不指定soname 的話,在編譯結連後的執行檔會以連時的library檔名為soname,並載入他。否則是載入soname指定的library檔案。可以利用objdump 來看library 的soname。

$ objdump -p libmylib.so | grep SONAME
SONAME libmylib.so.1

若不指名-soname參數的話,則library不會有這個欄位資料。在編譯後再用ln 來建立soname 與linker name 兩個檔案。

$ ln -s libmylib.so.1.0.0 libmylib.so
$ ln -s libmylib.so.1.0.0 libmylib.so.1

2.2 使用
與使用static library 同。

$ gcc main.c libmylib.so

以上直接指定與libmylib.so 連結。或用

$ gcc main.c -L. -lmylib

linker會搜尋libmylib.so 來進行連結。如果目錄下同時有static與shared library的話,會以shared為主。使用-static 參數可以避免使用shared連結。

$ gcc main.c -static -L. -lmylib

此時可以用ldd 看編譯出的執行檔與shared程式庫的相依性

$ldd a.out

linux-gate.so.1 => (0xffffe000)
libmylib.so.1 => not found
libc.so.6 => /lib/libc.so.6 (0xb7dd6000)
/lib/ld-linux.so.2 (0xb7f07000)

輸出結果顯示出該執行檔需要libmylib.so.1 這個shared library。會顯示not found 因為沒指定該library所在的目錄,所找不到該library。因為編譯時有指定-soname參數為libmylib.so.1 的關係,所以該執行檔會載入libmylib.so.1。否則以libmylib.so連結,執行檔則會變成要求載入libmylib.so

$ ./a.out

./a.out: error while loading shared libraries: libmylib.so.1
cannot open shared object file: No such file or directory

因為找不到libmylib.so.1 所以無法執行程式。有幾個方式可以處理。
a. 把libmylib.so.1 安裝到系統的library目錄,如/usr/lib下
b. 設定/etc/ld.so.conf ,加入一個新的library搜尋目錄,並執行ldconfig更新快取
c. 設定LD_LIBRARY_PATH 環境變數來搜尋library

這個例子是加入目前的目錄來搜尋要載作的library

$ LD_LIBRARY_PATH=. ./a.out
Hello world.


3. Dynamically loaded libraries
Dynamicaaly loaded libraries 才是像windows 所用的DLL ,在使用到時才載入,編譯連結時不需要相關的library。動態載入庫常被用於像plug-ins的應用。

3.1 使用方式
動態載入是透過一套dl function來處理。

#include
void *dlopen(const char *filename, int flag);
開啟載入filename 指定的library。

void *dlsym(void *handle, const char *symbol);
取得symbol 指定的symbol name在library被載入的記憶體位址。

int dlclose(void *handle);
關閉dlopen開啟的handle。

char *dlerror(void);
傳回最近所發生的錯誤訊息。

____ dltest.c ____
#include
#include
#include

int main() {
    void *handle;
    void (*f)();
    char *error;

    /* 開啟之前所撰寫的libmylib.so 程式庫*/
    handle = dlopen(“./libmylib.so”, RTLD_LAZY);
    if( !handle ) {
        fputs( dlerror(), stderr);
    exit(1);
    }

    /* 取得hello function 的address */
    f = dlsym(handle, “hello”);
    if(( error=dlerror())!=NULL) {
        fputs(error, stderr);
        exit(1);
    }
    /* 呼叫該function */
    f();
    dlclose(handle);
}

編譯時要加上-ldl 參數來與dl library 連結

$ gcc dltest.c -ldl

結果會印出Hello 字串

$ ./a.out

Hello

關於dl的詳細內容請參閱man dlopen


參考資料:
Creating a shared and static library with the gnu compiler [gcc]
http://www.adp-gmbh.ch/cpp/gcc/create_lib.html
Program Library HOWTO
http://tldp.org/HOWTO/Program-Library-HOWTO/index.html
APress – Definitive Guide to GCC

2014年10月8日 星期三

在ubuntu上,如何設定開機自動執行一些script

1. 針對個別使用者:請將指令加到 ~/.bashrc
    通常是將一些變數設定在此,讓terminal開啟時有一些環境變數可以用。
    如:
        export PATH=$JAVA_HOME/bin:$PATH

2. 針對系統開機時自動執行:請將指令加到 /etc/rc.local
    此檔案本身就有範例。

2014年7月28日 星期一

Android NDK setup in Eclipse.

網路上已經有太多文章教大家如何設定Eclipse裏面的NDK環境。

但是常常會發生一個狀況就是在Eclipse裏面找不到可以設定NDK路徑的地方。

本文即教大家如何讓NDK的選項出現,好設定NDK路徑。

網路上大家都說要在Eclipse \ Windows \ Preference \Android \ NDK 中設定路徑,但就是不知道什麼原因沒有出現上述的畫面,如下圖。

解決方式如下:
第一種 > 網路直接安裝:
1. 開啟 Eclipse \ Help \ Install New Software.
2. 在work with中設定

https://dl-ssl.google.com/android/eclipse/


3. 然後再按下旁邊的add,之後下方會出現一個可安裝的軟體列表。
4. 選擇所有軟體之後,進行下一步,逐步安裝。
5. 安裝完成之後,重新啟動Eclipse即可看見NDK選項。

第二種 > 下載到本機後安裝:
此種方法是上述的作法無法順利完成,可以採用第2種方法。
1. 先下載ADT到本機端。(下載後不需解壓縮)
2. 一樣開啟 Eclipse \ Help \ Install New Software.
3. 在work with中,先點選Add,會出現一個對話框。

4. 在對話框的Name裏面可以隨意填,只要自己認得即可。
5. 在對話框的Location選擇旁邊的Archive,然後選到第1步驟下載的檔案。
6. 接下來的步驟跟第一種方法的4, 5步驟相同。

完成之後,如同下圖。


2014年3月19日 星期三

adb device 無法發現裝置

前一陣子突然間手上的android device無法被ubuntu認識。
下了adb device指令一直沒有出現device裝置。

查了好幾個地方都沒有問題。
查看 /etc/udev/rules.d/99-android.rules也都正確。(參考資料)

最後同事教了一招。
在home目錄下有一個 .android 的目錄
裏面會有一個 adb_usb.ini 檔,請將 device 的 usb vendor id 加到此檔最後一行即可。
如何查詢device usb vendor id 請參考連結


最後檔案會如下範例:
$ cat .android/adb_usb.ini 
# ANDROID 3RD PARTY USB VENDOR ID LIST -- DO NOT EDIT.
# USE 'android update adb' TO GENERATE.
# 1 USB VENDOR ID PER LINE.
0x0110

其中,0x0110就是查出來的usb vendor id.

重新啟動adb一次就可以了。
$ adb kill-server
$ adb devices


2014年2月16日 星期日

在 ubuntu裡安裝sun java


  1. 下載JDK
    1. 首先下載官方的JDK. 官方網站有許多的選項,其中JDK是指Java Development Kit,如果你是開發人員,應該選擇這個。另外JRE是指Java Runtime Environment。
    2. 官方下載網站:http://www.oracle.com/technetwork/java/javase/downloads/index.html
    3. 接下來要選擇Java版本,Java分為許多版本,其中Java SE是指Standard Edition,選擇好一個版本之後,按下download,會連到更詳細的連結,這時請選擇你的OS平台,其中還分成rpm跟non-rpm,因為ubuntu不支援rpm安裝方式,所以請選擇non-rpm的版本下載。
    4. 以下假設下載的檔明為jdk6.bin
    5. 請先將此檔案改成可執行的權限
    6. chmod a+x jdk6.bin
    7. 直接執行它即可得到一個解壓縮的路徑
    8. ./jdk6.bin

  2. 安裝JDK
  3. 設定路徑
    1. export JAVA_HOME=/usr/java/jdk1.7.0 
  4. export PATH=$JAVA_HOME/bin:$PATH 
  5. export CLASSPATH=.:$JAVA_HOME/lib