2008年6月30日 星期一

How to know the version of different linux distributions

For Red-Hat
# cat /etc/redhat-release
Fedora release 8 (Werewolf)

$ cat /etc/debian_version
4.0

Romans 1:16

For I am not ashamed of the gospel, because it is God's power for the salvation of everyone who believes, of the Jew first and of the Greek as well

Your best life now

* 擴大你的視界
* 培養健康的自我形象
* 話語及思想所蘊藏的能力
* 讓過去成為過去
* 在困境中找到力量
* 為了施予而活
* 選擇快樂

2008年6月29日 星期日

ideal human characteristics

* To be a man of principle
* Obey the bible life
* Be consistent in your conversation/speaking while discussing with other persons

2008年6月25日 星期三

The Time of timezone

格林威治時間為標準時間(Greenwich Mean Time, GMT 時間), Greenwich is a city located in the England. And the time of Taiwan (Taipei) is GMT + 08:00

Daylight time generally is faster than the standard time.

All the timezones available in the America.
  • NST - Newfoundland Standard Time
  • NDT - Newfoundland Daylight Time
  • AST - Atlantic Standard Time
  • ADT - Atlantic Daylight Time
  • EST - Eastern Standard Time
  • EDT - Eastern Daylight Time
  • CST - Central Standard Time
  • CDT - Central Daylight Time
  • MDT - Mountain Daylight Time
  • PST - Pacific Standard Time
  • PDT - Pacific Daylight Time
  • AKST - Alaska Standard Time
  • AKDT - Alaska Daylight Time
  • HAST - Hawaii-Aleutian Standard Time
  • HADT - Hawaii-Aleutian Daylight Time


useful timezone related website
http://www.timeanddate.com/
http://wwp.greenwichmeantime.com/

2008年6月20日 星期五

The difference endline in the unix and windows

windows use the "\r\n" as the endline mark of one line. However linux just use the "\n" as the endline mark. So in the program sometimes we need to define the different end line mark according to the target platform.

#if defined(WIN32) || defined(_WIN32_WCE)
#define ENDLINE "\r\n"
#else
#define ENDLINE "\n"
#endif

Function pointer declaration

If you want to declare the function pointer, you can use the typedef command to produce a type that is a function pointer type, such as following (refer to the ortp package)

include/ortp/ortp.h
typedef void (*OrtpLogFunc)(OrtpLogLevel lev, const char *fmt, va_list args);

The following is another case which I have been ever used.
typedef void (* CALLBACK) (int);

ortp log architecture

ortp provide the logging apis for application using include
* ortp_log
* ortp_message
* ortp_warning
* ortp_error
* ortp_fatal

defined in the include/ortp/ortp.h
#ifdef ORTP_NOMESSAGE_MODE
#define ortp_log(...)
#define ortp_message(...)
#define ortp_warning(...)
#else
static inline void ortp_log(OrtpLogLevel lev, const char *fmt,...){
va_list args;
va_start (args, fmt);
ortp_logv(lev, fmt, args);
va_end (args);
}
[omit]
#endif

So if the compiler option (Makefile or header file) of application program doesn't define "ORTP_NOMESSAGE_MODE", than the ortp_log/ortp_message/ortp_warning will real output the logging messages

The function of real logging message is ortp_logv(lev, fmt, args)

let's look inside this function

include/ortp/ortp.h
#if !defined(WIN32) && !defined(_WIN32_WCE)
#define ortp_logv(level,fmt,args) \
{\
if (ortp_logv_out!=NULL && ortp_log_level_enabled(level)) \
ortp_logv_out(level,fmt,args);\
if ((level)==ORTP_FATAL) abort();\
}while(0)
#else
void ortp_logv(int level, const char *fmt, va_list args);
#endif

Currently we only focus on the linux platform. The ortp_logv was defined as a macro. It will make sure the ortp_logv_out is not a NULL function and the specified level is matched with the user preset level mask. And then the specified level log will output by the ortp_logv_out function.


Let's look inside the ortp_logv_out function
src/ortp.c
static void __ortp_logv_out(OrtpLogLevel lev, const char *fmt, va_list args);
OrtpLogFunc ortp_logv_out=__ortp_logv_out;
/**
*@param func: your logging function, compatible with the OrtpLogFunc prototype.
*
**/
void ortp_set_log_handler(OrtpLogFunc func){
ortp_logv_out=func;
}

the ortp_logv_out (which is the type of function pointer) was originally hardcode assign to the __ortp_logv_out. And the ortp_logv_out can be dynamically changed by the ortp_set_log_handle api to the user new defined logging function.

Let's look inside the __ortp_logv_out function in details

static void __ortp_logv_out(OrtpLogLevel lev, const char *fmt, va_list args){
const char *lname="undef";
char *msg;
if (__log_file==NULL) __log_file=stderr;
switch(lev){
case ORTP_DEBUG:
lname="debug";
break;
case ORTP_MESSAGE:
lname="message";
break;
case ORTP_WARNING:
lname="warning";
break;
case ORTP_ERROR:
lname="error";
break;
case ORTP_FATAL:
lname="fatal";
break;
default:
ortp_fatal("Bad level !");
}
msg=_strdup_vprintf(fmt,args);
fprintf(__log_file,"ortp-%s-%s" ENDLINE,lname,msg);
ortp_free(msg);
}

Finally __ortp_logv_out will output the api message to the specified direction (either FILE or stderr).


Additionally you can use ortp_set_log_file to change the api message output to the file descriptor (the default __log_file is set to NULL, so the api message will output to the stderr)
static FILE *__log_file=0;

/**
*@param file a FILE pointer where to output the ortp logs.
*
**/
void ortp_set_log_file(FILE *file)
{
__log_file=file;
}

Makefile tips and questions

xyz.a: a.o b.o c.o d.o
ar crv $@ $<

Q. I want to archive the whole objects (a.o b.o c.o d.o) into a single static library.
But I can't use the sign "$<" to refer all the afterward objects. It just include the first object, what sign should I use in this condition

The sign $^ seems can present the whole objects (a.o b.o c.o d.o). So maybe we can use the following presentation lines.
xyz.a: a.o b.o c.o d.o
ar crv $@ $^

2008年6月18日 星期三

denyhosts

How to run the denyhosts

# denyhosts-control start
will run the following command
# python /usr/bin/denyhosts.py --daemon --config=/etc/denyhosts.conf


delete the IP address entries which was record in the denyhost blocking list
(e.g.
BSD OS: /usr/share/denyhosts/data/hosts-restricted
Linux OS: /var/lib/denyhosts/hosts-restricted? /etc/hosts.deny? which one is correct I am not very sure?)

add IP white list into /etc/hosts.allow to bypass denyhost check
e.g.
/etc/hosts.allow
sshd: XXX.XXX.XXX.XXX

2008年6月10日 星期二

Linux Command - screen config example

the example of /etc/screenrc

vbell off
#sorendition rg
autodetach on
startup_message off
shell -$SHELL
allpartial off
#encoding utf-8
#utf8

bindkey "^[O5C" next
bindkey "^[[C" next
bindkey "^[O5D" prev
bindkey "^[[D" prev
bindkey "^[[1;5D" prev
bindkey "^[[1;5C" next

#set status bar
caption string "%w"
hardstatus on
hardstatus alwayslastline
hardstatus string "%w%=%m/%d %c"

2008年6月9日 星期一

Show the turn memory/cpu usage using top

Show the turn memory/cpu usage using top batch mode. Only single line, not all the processes.
# ps auxwww | grep kso
root 4 0.0 0.0 0 0 ? S< 11:36 0:00 [ksoftirqd/0]
root 3843 0.0 0.3 1672 508 pts/2 R+ 13:17 0:00 grep kso
# top -b -n1 -p4
top - 13:18:03 up 1:41, 5 users, load average: 0.00, 0.00, 0.00
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2%us, 0.1%sy, 0.0%ni, 99.6%id, 0.1%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 131284k total, 67716k used, 63568k free, 7020k buffers
Swap: 0k total, 0k used, 0k free, 41564k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4 root 15 -5 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0

TCP header digging

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Source Port Destination Port
Sequence Number
Acknowledgment Number
Data Offset reserved ECN Control Bits Window
Checksum Urgent Pointer
Options and padding :::
Data :::


Data Offset means the tcp header size (the total tcp header size is 4 * data offset value)

Example:
11:33:36.528451 IP (tos 0x0, ttl 119, id 7521, offset 0, flags [DF], proto TCP (6), length 52) 220.135.29.14.20715 > 140.113.28.230.ssh: S, cksum 0xff17 (correct), 2213150055:2213150055(0) win 64240
0x0000: 4500 0034 1d61 4000 7706 4376 dc87 1d0e E..4.a@.w.Cv....
0x0010: 8c71 1ce6 50eb 0016 83e9 fd67 0000 0000 .q..P......g....
0x0020: 8002 faf0 ff17 0000 0204 0584 0103 0300 ................
0x0030: 0101 0402

2008年6月4日 星期三

Why login sshd server so slowly or failed

If it is slowly to login ssh server...

the possible reasons for ssh Server
1. add "USEDNS no" in the /etc/ssh/ssh_config
2. remove the IPv6 related settings in the sshd server

the possible reasons for client
1. make sure you have properly configure the dns settings, because after the RSA@ssh negotiations, the ssh client will do some name resolution. If we don't properly configure the dns settings, this will slow down heavily the ssh client login processing (greater than 10 seconds).

If the login to ssh server was failed....
Sometimes while you are connect to the ssh server, you will receive the following information

# ssh 172.17.11.20
ssh_exchange_identification: Connection closed by remote host

This is probably the client IP address was added into the /etc/hosts.deny (such as DenyHosts package)

/etc/hosts.deny
# DenyHosts: Thu Jun 19 13:26:16 2008 | sshd: 172.17.1.10
#sshd: 172.17.1.10

2008年6月3日 星期二

Linux Command - cvs

When you try to commit a code, sometimes it will happen conflict like following conditions.

# cvs -q up test.c
user@cvs-server's password:
[omit]
retrieving revision 1.1.1.1 ==> retrieve the version 1.1.1.1, I don't know why need to retrieve this version, why not retrieve the version 1.1
retrieving revision 1.2 ==> retrieve the version 1.2
Merging differences between 1.1.1.1 and 1.2 into test.c ==> I don't understand why here is merge the difference of 1.1.1.1 and 1.2
rcsmerge: warning: conflicts during merge
cvs update: conflicts found in test.c
C test.c

In the test.c, you will find...
<<<<<<< a="b+1;"> the new modified in the working directory but not yet update to the cvs server.
=======
a=c+1; ==> the latest (newest) version code existed in the cvs server. We must resolve the conflicted part between the modified code which is existed in the working directory with this newest one which is existed in the cvs server.
>>>>>>> 1.2


If the CVS/Entries appear the follwoing line, it means that it is a new added but not yet commited file

/a.cfg/0/dummy timestamp//
normally file will like the following one
/b123.c/1.3/Mon Apr 21 06:36:39 2008//

How to create a cvs branch

# cvs rtag -b branch_name module_name

2.1 Creating a Branch
Branches can be added to the repository tree in order to allow different development paths to be tried, or to add parallel development of code to different base versions. To create a branch, you can use

cvs tag (從目前的Working Directory 切branch)

or

cvs rtag (從Repository 的 main trunk 切出 branch)

with the -b option.

Do not be fooled! Even though the same commands can be used to create tags, branches are completely different than tags.

2.1.1 rtag
To create a branch from the main trunk of my_module at the revision that was last committed, use the command
cvs rtag -b Branchname my_module

To create a branch from a tagged revision of my_module, use the command
cvs rtag -r Tagname -b Branchname my_module

Both commands immediately create a branch in the repository without requiring a cvs commit to enact. You do not need to be in a checked-out working directory to do this.
2.1.2 tag
If you are in a working directory, you can create a new branch in the branch or trunk from which you checked out your working directory (not including the changes you've made to your working directory since the last commit) by using the command
cvs tag -b Branchname

Like rtag, the change is immediate, and does not wait for a commit command.

Your working directory remains on the old branch, at a point after the branch you just created. To move your working directory to the new branch, use the command
cvs update -r Branchname When you are finished making changes to your working directory, save it as the next revision on the new branch with
cvs commit
2.1.3 Both rtag and tag
Note that both rtag and tag work directly on the repository and take effect immediately without a commit command. Rtag takes effect at the specified place (the end of the main trunk by default), while tag takes effect at the place where the working directory was checked out or last committed.
==>根據這邊的說明, 建議在切CVS branch時, 不要利用tag, 盡量利用rtag, 因為working directory 有可能每一個檔案它的revision, branch 都不同, 利用tag 切會容易有confuse, 結果可能不是我們想要的


How to removing a empty directory from working directory. Simply type the following commands
# cvs -q up -P

Removing directories

In concept removing directories is somewhat similar to removing files--you want the directory to not exist in your current working directories, but you also want to be able to retrieve old releases in which the directory existed.

The way that you remove a directory is to remove all the files in it. You don't remove the directory itself; there is no way to do that. Instead you specify the `-P' option to cvs update, cvs checkout, or cvs export, which will cause CVS to remove empty directories from working directories. Probably the best way to do this is to always specify `-P'; if you want an empty directory then put a dummy file (for example `.keepme') in it to prevent `-P' from removing it.

Note that `-P' is implied by the `-r' or `-D' options of checkout and export. This way CVS will be able to correctly create the directory or not depending on whether the particular version you are checking out contains any files in that directory.


cvs login ==> this command can use to login to the CVS Server for SSO (Single Sign On)
cvs -d :ssh:uer@IP-Address:/home/cvs login

Frequency Questions.

Q.
# cvs -q up -d
cvs [update aborted]: could not chdir to XXXX/loadfile: Not a directory

A. The problem was existed on the client (CVS client) end. There is a file called
'XXXX/loadfile' in the way of creating that directory?

Try deleting it then rerun the "cvs update -A" command?

Netfilter packet flow diagram

2008年6月1日 星期日

the static/shared library creating process (according the uuid package)

mkdir .libs
#-----------------------------------------------------------------------------------
# In the following process, we compile both the object files for the shared/static library using
#-----------------------------------------------------------------------------------
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid.c -fPIC -DPIC -o .libs/uuid.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid.c -o uuid.o >/dev/null 2>&1
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_md5.c -fPIC -DPIC -o .libs/uuid_md5.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_md5.c -o uuid_md5.o >/dev/null 2>&1
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_sha1.c -fPIC -DPIC -o .libs/uuid_sha1.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_sha1.c -o uuid_sha1.o >/dev/null 2>&1
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_prng.c -fPIC -DPIC -o .libs/uuid_prng.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_prng.c -o uuid_prng.o >/dev/null 2>&1
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_mac.c -fPIC -DPIC -o .libs/uuid_mac.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_mac.c -o uuid_mac.o >/dev/null 2>&1
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_time.c -fPIC -DPIC -o .libs/uuid_time.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_time.c -o uuid_time.o >/dev/null 2>&1
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_ui64.c -fPIC -DPIC -o .libs/uuid_ui64.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_ui64.c -o uuid_ui64.o >/dev/null 2>&1
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_ui128.c -fPIC -DPIC -o .libs/uuid_ui128.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_ui128.c -o uuid_ui128.o >/dev/null 2>&1
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_str.c -fPIC -DPIC -o .libs/uuid_str.o
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_str.c -o uuid_str.o >/dev/null 2>&1
# compile the shared library
gcc -shared .libs/uuid.o .libs/uuid_md5.o .libs/uuid_sha1.o .libs/uuid_prng.o .libs/uuid_mac.o .libs/uuid_time.o .libs/uuid_ui64.o .libs/uuid_ui128.o .libs/uuid_str.o -Wl,-soname -Wl,libuuid.so.16 -o .libs/libuuid.so.16.0.21
# do the shared libray linkage
(cd .libs && rm -f libuuid.so.16 && ln -s libuuid.so.16.0.21 libuuid.so.16)
(cd .libs && rm -f libuuid.so && ln -s libuuid.so.16.0.21 libuuid.so)
# do the static library linkage, using ar
ar cru .libs/libuuid.a uuid.o uuid_md5.o uuid_sha1.o uuid_prng.o uuid_mac.o uuid_time.o uuid_ui64.o uuid_ui128.o uuid_str.o
# using ranlib
ranlib .libs/libuuid.a
creating libuuid.la
# creating the libuuid.la for libtool library file using
(cd .libs && rm -f libuuid.la && ln -s ../libuuid.la libuuid.la)
gcc -I. -I. -DHAVE_CONFIG_H -O2 -pipe -c uuid_cli.c
# build the uuid application program
gcc -o .libs/uuid uuid_cli.o ./.libs/libuuid.so -lnsl -Wl,--rpath -Wl,/tmp/uuidtmp/lib
creating uuid


Q. the option "-pipe" of gcc means?
Q. -Wl,--rpath -Wl,/tmp/uuidtmp/lib means?
pass the option to the linker, the comma sign will replace with space while passing into the linker (ld)
Q. When we compile an object file. What is the difference if we direct compile the library of just link the library? for example
# gcc a.o b.o libxyz.a -o hello
# gcc a.o b.o -lxyz -o heelo ==> the command format is wrong
==> You must let the linked library parameter -lxyz behind the output executable file (-o hello)
What is the difference in the above 2 items? (Basically they all can work)
The ld need to place the linked library behind the output executing file, like the following command

This is an important trick/tip :( (I am failed many times in this point... )

# gcc a.o b.o -o heelo -lxyz