2013年3月27日 星期三

mDNS / zeroconf - mDNSResponder 與 cmake @ Ubuntu 12.04 64Bit

最近又把玩 mDNS 了,記得第一次接觸時是用 zeroconf python 程式,這次就改用 Apple 的 Open Source - mDNSResponder  啦


整理了一下後,就用 cmake 當 script 來把玩吧!


$ git clone https://github.com/changyy/mDNSResponder-cmake.git
$ cd mDNSResponder-cmake
$ mkdir build
$ cd build
$ cmake ..
$ make
$ ls bin
mdns_client mdns_responder
$ ./bin/mdns_responder -t _study._tcp. -d local -n changyy -b
$ ./bin/mdns_client -t _study._tcp.
Hit ^C when you're bored waiting for responses.
*** Found name = 'changyy', type = '_study._tcp.', domain = 'local.'


2013年3月26日 星期二

[Tarball] 更新系統內建 Nginx 筆記 @ Ubuntu 12.04 Server 64Bit

最近要來更新一下 nginx 了,目的是想使用第三方 modules,並希望依據 Ubuntu 內建 nginx 的佈設規劃。


作法就是用內建 nginx -V 查看目前編譯所下的指令,接著下載新版 nginx 後,再下載第三方 modules 後,就可以編一編,補一補缺的 library 後,即可收工。


$ which nginx
/usr/sbin/nginx
$ nginx -V
nginx version: nginx/1.1.19
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-debug --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_mp4_module --with-http_perl_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-auth-pam --add-module=/build/buildd/nginx-1.1.19/debian/modules/chunkin-nginx-module --add-module=/build/buildd/nginx-1.1.19/debian/modules/headers-more-nginx-module --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-development-kit --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-echo --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-http-push --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-lua --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-upload-module --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-upload-progress --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-upstream-fair --add-module=/build/buildd/nginx-1.1.19/debian/modules/nginx-dav-ext-module


$ cd /tmp
$ curl http://nginx.org/download/nginx-1.3.14.tar.gz | tar -xzvf -
$ cd nginx-1.3.14 && mkdir modules
$ cd modules
$ git clone git://github.com/chaoslawful/lua-nginx-module.git
$ cd /tmp/nginx-1.3.14
$ ./configure --sbin-path=/usr/sbin/nginx --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-debug --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_mp4_module --with-http_perl_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=modules/lua-nginx-module


Configuration summary
+ using system PCRE library
+ using system OpenSSL library
+ md5: using OpenSSL library
+ sha1: using OpenSSL library
+ using system zlib library


nginx path prefix: "/etc/nginx"
nginx binary file: "/usr/sbin/nginx"
nginx configuration prefix: "/etc/nginx"
nginx configuration file: "/etc/nginx/nginx.conf"
nginx pid file: "/var/run/nginx.pid"
nginx error log file: "/var/log/nginx/error.log"
nginx http access log file: "/var/log/nginx/access.log"
nginx http client request body temporary files: "/var/lib/nginx/body"
nginx http proxy temporary files: "/var/lib/nginx/proxy"
nginx http fastcgi temporary files: "/var/lib/nginx/fastcgi"
nginx http uwsgi temporary files: "/var/lib/nginx/uwsgi"
nginx http scgi temporary files: "/var/lib/nginx/scgi"


$ make
$ sudo nginx -s stop
$ sudo apt-get remove nginx
$ sudo make install
$ nginx -v
nginx version: nginx/1.3.14
$ sudo service nginx start


不過,其實上述除了將 nginx 更新為 1.3.14 外,其實還很多 modules 未安裝,可以先用 apt-get source 查看 Ubuntu 內建的 modules


$ sudo apt-get source nginx
$ ls nginx-1.1.19/debian/modules/
chunkin-nginx-module nginx-auth-pam nginx-development-kit nginx-lua nginx-upstream-fair
headers-more-nginx-module nginx-cache-purge nginx-echo nginx-upload-module README.Modules-versions
naxsi nginx-dav-ext-module nginx-http-push nginx-upload-progress


因此,若只增加第三方 modules 的話,且該 modules 可在 1.1.19 運行的話,也能考慮用 apt-get source 後,把第三方 modules 擺好,再 configure 為原先 nginx 的項目外,再增加一個 ---add-module=/path/3rdModules/name 即可。此外,編譯第三方 modules 時,碰到一些 warning 訊息,可以考慮 configure 時多增加 --with-cc-opt=-Wno-error 來避開(不然就手動去改 source code)。


其他 Ubuntu 額外安裝項目: 


$ sudo apt-get install libsp-gxmlcpp-dev libgd2-xpm-dev libgeoip-dev libperl-dev libluajit-5.1-dev liblua5.2-dev


2013年3月23日 星期六

[C] Portable Catdoc

Catdoc 是一套 GNU Public License Open Source,最近摸了一下,稍微改動了一點地方,主要原因是 catdoc 在找尋字碼表時,會採用原先在 compile time 所下的 define 關鍵字,這意味著程式若要搬移必須重制原先編譯時期所決定的相關目錄結構才行,例如一開始編譯時,就說字碼將安裝在 /usr/local/share/catdoc 下,那你把 binary 程式去另一台機器時,也必須把字碼一樣設置相同的路徑才行。


因此花了一點時間看了一下,還滿容易的,僅需把兩個變數(charset_path, map_path)的定義參數化,因為那個字碼路徑(CHARSETPATH)在各個程式之間算共享的資訊,在 C 語言中就是透過定義一份記憶體位置,其他用 extern 的方式來連結存取。改完後在多設個參數(-r /path/charsets)讓執行時可以初始化就好。


程式碼:


https://github.com/changyy/catdoc-portable


詳細流程:


diff --git a/catdoc-0.94.2/src/catdoc.c b/catdoc-0.94.2/src/catdoc.c
index d8270fd..c3729a4 100644
--- a/catdoc-0.94.2/src/catdoc.c
+++ b/catdoc-0.94.2/src/catdoc.c
@@ -35,6 +35,8 @@ int _argc;
/* Processes options, reads charsets files and substitution */
/* maps and passes all remaining args to processfile */
/**************************************************************/
+char *charset_path = NULL;
+char *map_path = NULL;
int main(int argc, char **argv) {
FILE *f;
int c,i;
@@ -56,8 +58,15 @@ int main(int argc, char **argv) {
#ifdef HAVE_LANGINFO
get_locale_charset();
#endif
- while ((c=getopt(argc,argv,"Vls:d:f:taubxv8wm:"))!=-1) {
+ charset_path = strdup(CHARSETPATH);
+ map_path = charset_path;
+ while ((c=getopt(argc,argv,"Vls:d:f:taubxv8wm:r:"))!=-1) {
switch (c) {
+ case 'r':
+ free(charset_path);
+ charset_path = strdup(optarg);
+ map_path = charset_path;
+ break;
case 's':
check_charset(&source_csname,optarg);
forced_charset = 1;
@@ -181,12 +190,13 @@ int main(int argc, char **argv) {
fclose(f);
}
}
+ free(charset_path);
return c;
}
/************************************************************************/
/* Displays help message */
/************************************************************************/
void help (void) {
- printf("Usage:\n catdoc [-vu8btawxlV] [-m number] [-s charset] "
+ printf("Usage:\n catdoc [-vu8btawxlV] [-r /path/charsets] [-m number] [-s charset] "
"[-d charset] [ -f format] files\n");
}
diff --git a/catdoc-0.94.2/src/catppt.c b/catdoc-0.94.2/src/catppt.c
index 50fc04c..f74307a 100644
--- a/catdoc-0.94.2/src/catppt.c
+++ b/catdoc-0.94.2/src/catppt.c
@@ -34,7 +34,7 @@
*
*/
void help (void) {
- printf("Usage:\n ppt2text [-lV] [-b string] [-s charset] [-d charset] files\n");
+ printf("Usage:\n ppt2text [-lV] [-r /path/charsets] [-b string] [-s charset] [-d charset] files\n");
}


@@ -48,6 +48,8 @@ char *input_buffer, *output_buffer;
*
* @return
*/
+char *charset_path = NULL;
+char *map_path = NULL;
int main(int argc, char *argv[]) {
FILE *input;
FILE *new_file, *ole_file;
@@ -68,10 +70,17 @@ int main(int argc, char *argv[]) {
get_locale_charset();
#endif

+ charset_path = strdup(CHARSETPATH);
+ map_path = charset_path;
check_charset(&dest_csname,dest_csname);

- while ((c=getopt(argc,argv,"Vls:d:p:"))!=-1) {
+ while ((c=getopt(argc,argv,"Vls:d:p:r:"))!=-1) {
switch(c) {
+ case 'r':
+ free(charset_path);
+ charset_path = strdup(optarg);
+ map_path = charset_path;
+ break;
case 'l':
list_charsets(); exit(0);
case 's':
@@ -153,5 +162,6 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "%s is not OLE file or Error\n", filename);
}
}
+ free(charset_path);
return 0;
}
diff --git a/catdoc-0.94.2/src/charsets.c b/catdoc-0.94.2/src/charsets.c
index b52a1eb..9c0b699 100644
--- a/catdoc-0.94.2/src/charsets.c
+++ b/catdoc-0.94.2/src/charsets.c
@@ -12,7 +12,7 @@
#include <stdlib.h>
#include "catdoc.h"

-char *charset_path=CHARSETPATH;
+//char *charset_path=CHARSETPATH;
char *source_csname=SOURCE_CHARSET, *dest_csname=TARGET_CHARSET;
short int * source_charset;
int unknown_as_hex=0;
diff --git a/catdoc-0.94.2/src/substmap.c b/catdoc-0.94.2/src/substmap.c
index f29d629..a609a4c 100644
--- a/catdoc-0.94.2/src/substmap.c
+++ b/catdoc-0.94.2/src/substmap.c
@@ -13,7 +13,7 @@
#include <stdlib.h>
#include "catdoc.h"
SUBSTMAP spec_chars, replacements;
-char *map_path=CHARSETPATH;
+//char *map_path=CHARSETPATH;
void map_insert(SUBSTMAP map, int uc, const char *s) ;
int longest_sequence=6;/* six is longest character sequence which can be
generated by catdoc internally*/
diff --git a/catdoc-0.94.2/src/xls2csv.c b/catdoc-0.94.2/src/xls2csv.c
index 243e801..34184d1 100644
--- a/catdoc-0.94.2/src/xls2csv.c
+++ b/catdoc-0.94.2/src/xls2csv.c
@@ -31,13 +31,15 @@ extern char *sheet_separator;
/* Displays help message */
/************************************************************************/
void help (void) {
- printf("Usage:\n xls2csv [-xlV] [-g number] [-f date-format] [-b string] [-s charset] [-d charset] [-c char] [ -q number] files\n");
+ printf("Usage:\n xls2csv [-xlV] [-r /path/charsets] [-g number] [-f date-format] [-b string] [-s charset] [-d charset] [-c char] [ -q number] files\n");
}
/* Defines unicode chars which should be
replaced by strings before UNICODE->target chatset
mappigs are applied i.e. TeX special chars like %
*/
char *input_buffer, *output_buffer;
+char *charset_path = NULL;
+char *map_path = NULL;
int main(int argc, char *argv[])
{
FILE *input;
@@ -58,11 +60,17 @@ int main(int argc, char *argv[])
#ifdef HAVE_LANGINFO
get_locale_charset();
#endif
-
+ charset_path = strdup(CHARSETPATH);
+ map_path = charset_path;
check_charset(&dest_csname,dest_csname);
-
- while ((c=getopt(argc,argv,"Vlf:s:d:xq:c:b:g:p:"))!=-1) {
+
+ while ((c=getopt(argc,argv,"Vlf:s:d:xq:c:b:g:p:r:"))!=-1) {
switch(c) {
+ case 'r':
+ free(charset_path);
+ charset_path = strdup(optarg);
+ map_path = charset_path;
+ break;
case 'l':
list_charsets(); exit(0);
case 'x':
@@ -176,5 +184,6 @@ int main(int argc, char *argv[])
fprintf(stderr, "%s is not OLE file or Error\n", filename);
}
}
+ free(charset_path);
return 0;
}


 


2013年3月16日 星期六

[電影] Life of π


圖:http://en.wikipedia.org/wiki/Life_of_Pi_(film)


終於播空看了 π 電影,這拍的真的不錯,裡頭寓意深遠,我還滿喜歡這種劇情。讓我想起昨天跟高中同學短暫閒聊的內容,那位同學恰巧經過台北,拿了帖子給我,在法拉利車廠前,我們閒聊了幾句。那段閒聊或許有些傲氣,拋棄了當前的工作,正籌備著回老鄉創業,同學提醒著我要訂立目標,珍惜現況顛峰,大膽追求,並且學習力可能會慢慢遞減,更要思考十年後要該端出哪盤菜呢!


看完 π 後,更清楚那種觸感,雖說大家都朝著舒適的環境追求,但只有活在有競爭環境下,才會督促自己走的更遠一點。


2013年3月15日 星期五

gdb: error while loading shared libraries: libexpat.so.0: cannot open shared object file: No such file or directory @ Ubuntu 12.04 Server 64Bit

原先以為安裝 libexpat1-dev 後即可解決,但有更多細節該留意,就順手記一下吧


$ sudo find / -name "libexpat.so*"
/lib/x86_64-linux-gnu/libexpat.so.1.5.2
/lib/x86_64-linux-gnu/libexpat.so.1
$ sudo ln -s /lib/x86_64-linux-gnu/libexpat.so.1 /lib/i386-linux-gnu/libexpat.so.0
$ sudo ldconfig
$ gdb
gdb: error while loading shared libraries: libexpat.so.0: wrong ELF class: ELFCLASS64
$ sudo apt-get install ia32-libs
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:


The following packages have unmet dependencies:
ia32-libs : Depends: ia32-libs-multiarch
E: Unable to correct problems, you have held broken packages.
$ dpkg --print-architecture
amd64
$ dpkg --print-foreign-architectures
i386
$ sudo unlink /lib/i386-linux-gnu/libexpat.so.0
$ sudo apt-get install libexpat1-dev:i386
$ sudo ln -s /lib/i386-linux-gnu/libexpat.so.1 /lib/i386-linux-gnu/libexpat.so.0
$ gdb

(gdb)


2013年3月9日 星期六

[C] XML parser using libroxml

複習一下 C 語言和 cmake 用法,這次用 C 來解 XML,至於為何要用 libroxml(LGPL) 嘛,只是單純碰到就用看看(且預設支援cmake),下次再改用 libxml2(MIT)。


處理一些 XML 時,會需要排版一下才方便人眼查看,這時就用到 Online XML Formatter 來格式化一下。


筆記:https://github.com/changyy/c-xml-parser-using-libroxml


$ git clone --recursive git://github.com/changyy/c-xml-parser-using-libroxml.git
$ cd c-xml-parser-using-libroxml
$ mkdir build
$ cd build
$ cmake ..
$ ./c-xml-parser


2013年3月3日 星期日

We Are Young!


這首歌的意境有很多的解釋方向,但此刻就不多說,享受那股年輕氣盛吧!最近花了兩個週末補齊了我錯估時程的工作 :P 真的,用說的都嘛比較快,不知不覺就說錯看錯估錯寫錯...


對這首歌歌詞有興趣的可以參考 fun.搖滾樂團-we-are-young-ft.-janelle-monáe-【中英歌詞】,翻的還不賴。


Tonight
We are young
So let's set the world on fire
We can burn brighter than the sun


最近周邊人的轉職、猶豫,都常讓我回顧自己去年的選擇方式,的確,就那幾個字罷了,我們還年輕,再衝動一點、再勇敢一點,再給自己多一點時間來驗證吧!


2013年3月1日 星期五

Redmine - 修正檔案上傳失敗

用 Redmine 附檔時只會看到 Internal Server Error 資訊,翻了 /var/log/apache2/error.log 後,看到了神祕句子:


Unexpected error in mod_passenger: An error occured while buffering HTTP upload data to a temporary file in /tmp/passenger.1.0.7336/generation-0/buffered_uploads. The current Apache worker process (which is running as XXX) doesn't have permissions to write to this directory. Please change the permissions for this directory (as well as all parent directories) so that it is writable by the Apache worker process, or set the 'PassengerUploadBufferDir' directive to a directory that Apache can write to.
Backtrace:
  in 'boost::shared_ptr<Passenger::BufferedUpload> Hooks::receiveRequestBody(request_rec*)' (Hooks.cpp:1321)
  in 'int Hooks::handleRequest(request_rec*)' (Hooks.cpp:585)


這時我才想到,因為我在 Apache 設定時,透過 passenger 並指定 XXX 權限跑 redmine 的,因此會碰到 XXX 無法存取 /tmp 裡頭相關的位置,解法…那就是多建立一個目錄給 redmine 使用吧 :P


$ sudo su XXX
$ mkdir /path/redmine/PassengerUploadBufferDir
$ exit
$ sudo vim /etc/apache2/conf.d/redmine
Alias /redmine "/path/redmine/public"
RailsBaseURI /redmine
<Directory /path/redmine/public>
  AssignUserId XXX XXX
  PassengerUploadBufferDir /path/redmine/PassengerUploadBufferDir
  AllowOverride all
  Options -MultiViews
</Directory>


Redmine - 修正 attachments 資料

忘記是從哪個版本開始 XD 總之,現在將 Redmine 升到 2.3.0.devel 版本,請參考官方:http://www.redmine.org/projects/redmine/wiki/RedmineUpgrade


後來發現,以前的 attachments 都不能下載,仔細確認後,發現這跟 db schema 有關,直接翻 db 後,發現多了個欄位 disk_directory,所以在 redmine/files 規劃已經改成 redmine/files/YEAR/MONTH 的結構,故只需建立對應的結構後,在把 db 資料更新一下即可,如:


$ mkdir -p /path/redmine/files/2013/01
$ mv /path/redmine/files/* /path/redmine/files/2013/01
$ cp /path/redmine/db/production.db /path/redmine/db/production.db-backup
$ sqlite3 /path/redmine/db/production.db
sqlite> SELECT * FROM attachments WHERE ifnull(disk_directory,'') = '';
sqlite> UPDATE attachments SET disk_directory = "2013/01" WHERE ifnull(disk_directory,'') = '';


收工