Mar 30, 2009

展喜犒师

齐孝公伐我北鄙,公使展喜犒师,使受命于展禽。

齐侯未入竟,展喜从之,曰:“寡君闻君亲举玉趾,将辱于敝邑,使下臣犒执事。”齐侯曰:“鲁人恐乎?”对曰:“小人恐矣,君子则否。”齐侯曰:“室如县罄,野无青草,何恃而不恐?”对曰:“恃先王之命。昔周公、大公股肱周室,夹辅成王。成王劳之,而赐之盟,曰‘世世子孙无相害也’!载在盟府,太师职之。桓公是以纠命诸侯,而谋其不协,弥缝其阙,而匡救其灾,昭旧职也。及君即位,诸侯之望曰:‘其率桓之功!’我敝邑用不敢保聚,曰:‘岂其嗣世九年,而弃命废职?其若先君何?君必不然。’恃此以不恐。”

齐侯乃还。

一直觉得春秋是个很神奇的时代。其神奇之处,在《古文观止》选自《左传》的这篇文章中就有体现。

齐孝公要侵伐鲁国,还没有到边境,就碰见了前来“犒师”的鲁国大夫展喜。对于齐孝公所谋,两方面都是心知肚明的。齐孝公做事也够光棍,劈头就是一句“我要打你国,你国人害怕不?”展喜倒也从容,“小人恐矣,君子则否”。齐孝公就纳闷了,你鲁国又贫又弱,地里连根草都不长,你凭什么不害怕?展喜就说,君子们不害怕的原因不是我国国立很强,而是你我两国关系好啊,老早就是睦邻友好关系了;而且,您爹是个大好人呀,您肯定也是好人,好人怎么会打别人呢?齐孝公一听,“嗯,说的不错,在理。我不能打你,还是回去好了。”齐侯乃还。

战争是游戏吗?不是啊。它关系着国家与人民的命运,是需要严肃认真对待,一点也轻忽不得的。可是,明明已经征伐途中,就要到开战了,却因为听到敌方的几句奉承话就要取消行动,打道回府?!难道发兵前不需要庭前商议、没有对战争将会带来的后果通盘考虑吗?唉,战争就是儿戏,君主的一念可以兴兵,一念可以弥祸。

那么让齐孝公在意的到底是什么?名。或者说义?那么,义到底是什么?在我看来,就是面子。礼义廉耻,都是如此。大概是没有经历之后2000年时间的磨砺吧,他们看不清战争的真正面目——利益,不知道利益攸关、当仁不让的道理。现如今流行“没有永远的朋友,只有永远的利益”这种利益至上观也似乎不被认同。唉,想想看,归根到底,想占有大义、想他人守礼、想成就霸主,这些只是想想就会得到的吗?不是啊。强大的实力才是这一切的坚实后盾!而鲁国正值饥荒,这时候去侵略他正是增强自己实力的好机会。都已经要这么做了,却又半途而废,还真不是霸主的料啊!

P.S.:上面的“展禽”就是大名鼎鼎的坐怀不乱柳下惠啊!

Mar 26, 2009

swapping two variables without using a temp var

http://www.devmaster.net/forums/showthread.php?t=428

Mar 20, 2009

Blogging with Windows Live Writer (WLW) from Ubuntu

Not long ago as for my CPE416 Distributed Systems assignment I installed a second OS Ubuntu plus the pre-installed Windows to my Thinkpad T43. Ubuntu is great and I thought I would erase the whole hardhard and then switch from Windows to Ubuntu completely. Before I actually carried out this I found some Windows thing that I would miss from Ubuntu. That is Windows Live Writer. I really like this piece of software - it helps me a lot when I update my blog. Ahhh, then what to do?

Now the problem is solved (nothing is difficult if you take serious of it! :)). I came across this post "How to install Windows Live Writer in Ubuntu(Linux)" when google-ing for the solution. It is easy to deal with the problem. As the blog owner Harihara Kumar put it, what I need to do is just follow the precedure "VirtualBox -> Windows -> WLW". And now it's time to starting blogging locally with WLW!

Following is a screen shot of WLW in Windows in VirutalBox in Ubuntu. hahah!

===============

Don't know what is VirutalBox? "VirtualBox is a general-purpose full virtualizer for x86 hardware. Targeted at server, desktop and embedded use, it is now the only professional-quality virtualization solution that is also Open Source Software. " Want more? No problem. Take a look at its official site: Here.

Mar 19, 2009

linux下c语言socket programming的timeout

cpe416 distributed systems课上的作业要求写一个简单的socket(UDP) program - facility booking system,用client-server的模式写。其中有一个timeout的要求,意思是:client给server发送一个请求,过了一段时间(譬如5秒)之后(timeout了)如果没有收到server的回复,client要再次给server发送请求。

我们group是在linux下用C写这个的,到了timeout这个地方的时候,在网上找到了一个例子。但是原本的code显示timeout功能不怎么明了,我把它改了一点,如下:

#include <STDIO.H> 
#include <SYS/time.h>
#include <SIGNAL.H>
#include <STDLIB.H>

void catch_alarm(int);
void aaa();

int main(){
// install signal hander catch_alarm
// to handle the signal SIGALRM
signal(SIGALRM, catch_alarm);
// to start the timer
alarm(5);

aaa();

return EXIT_SUCCESS;
}

// this is the handler called by kernal
// when timer counts to 0
void catch_alarm(int sig){
printf("Alarm Occurred.\n");
}

// pause at the scanf() line to demonstrate
// the timeout function
void aaa(){
int x;
printf("Please enter an integer: ");
// pause at this line
// after catch_alarm() handles the SIGALRM
// signal, this method continues from here
scanf("%d", &x);
printf("You entered %d.\n", x);
}

上面的signal和alarm两个function是这个timeout的重点了。signal这个function的作用呢,正如comments上面些的那样,它会install一个signal handler给SIGALRM这个signal。然后呢,等这个signal到了的时候“signal handler function for a signal is called ’catching the signal‘.”那么,什么时候这个signal来到?这要看alarm()中写了什么。alarm的定义为:

unsigned int alarm(unsigned int seconds); 

alarm()的作用就是会让系统在seconds秒之后generate一个SIGALRM的信号来,这个时候signal handler也就是catch_alarm()这个么method就会被调用来处理这个signal了。

signal被处理以后这个程序是怎么往下走的呢,这就是上面的例子所要演示的了。当程序print出来“Please enter an integer:“的时候现不要输东西,等到五秒过后,屏幕上会出来“Alarm Occurred.”字样,这说明signal已经来了,而catch_alarm被调用了。这时候再随便打一个数字,按enter,屏幕上又会有“You entered .”字样。这说明signal来的时候,主程序暂停,handler被调用。而handle过了以后,主程序从哪里停的,它便会从哪里继续下去。

Mar 7, 2009

用程序模拟键盘按键

小众软件的文章“Win7 Appinn Desktop - 模拟 Windows 7 的盲按显示桌面效果”介绍了一个把鼠标移到屏幕左上角或者右下角点一下就可以做到“Win+D”效果的小程序。

这是个挺不错的应用,但是尽管原程序只有几百KB,运行以后它要用到5-6MB。我觉得程序中或许有冗余的东西,不过原程序是用AutoHotkey写的,我对AHK不是很熟悉——确切的说,我也不是很喜欢AHK这类语言。or程序?所以我想要自己写个类似的东西。不过,说实话我的能力实在不是很强。幸好还有Google大婶在。

首先我要做的是实现——用程序模拟键盘按键。

先看一下下面的乱七八糟的C++ code。

// CPP_SimulateWinD.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>

/***********
int _tmain(int argc, _TCHAR* argv[])
{
printf("Program Started...\n\n");
LASTINPUTINFO myInfo;
myInfo.cbSize = sizeof(myInfo);
BOOL myResult = GetLastInputInfo(&myInfo);
if(myResult) printf("Get info successfully...");
printf("...Program Completed\n\n");

system("PAUSE");
return 0;
}
*******************/

INPUT *key;
INPUT *key2;
INPUT Inputs[2];

void _SendInput(char ch);
void _SendInput();
void _SendInputV2();

void main(){

char end;
HWND windowHandle = FindWindow(0, "*new 1 - Notepad++");
//INPUT *key;
if(windowHandle == NULL)
printf("Notepad++ window not found.");
SetForegroundWindow(windowHandle);
Sleep(1000);

key = new INPUT;
key2 = new INPUT;
//for(int i='A'; i<'Z'; i++){
// _SendInput(i);
//}
//_SendInput();
_SendInputV2();
printf("Key inputted.");

system("PAUSE");
}

void _SendInput(char ch){
key->type = INPUT_KEYBOARD;
key->ki.wVk = ch;
//key->ki.wVk = VK_LWIN;
key->ki.dwFlags = 0;
key->ki.time = 0;
key->ki.wScan = 0;
key->ki.dwExtraInfo = KEYEVENTF_KEYUP;
SendInput(1, key, sizeof(INPUT));
//key->ki.dwExtraInfo = KEYEVENTF_KEYUP;
//SendInput(1, key, sizeof(INPUT));
Sleep(500);
}

void _SendInput(){
key->type = INPUT_KEYBOARD;
//key->ki.wVk = 'D';
key->ki.wVk = VK_LWIN;
key->ki.dwFlags = 0;
key->ki.time = 0;
key->ki.wScan = 0;
//key->ki.dwExtraInfo = KEYEVENTF_KEYUP;
key->ki.dwExtraInfo = 0;
SendInput(1, key, sizeof(INPUT));

key2->type = INPUT_KEYBOARD;
key2->ki.wVk = 'D';
//key2->ki.wVk = VK_LWIN;
key2->ki.dwFlags = 0;
key2->ki.time = 0;
key2->ki.wScan = 0;
//key2->ki.dwExtraInfo = KEYEVENTF_KEYUP;
key2->ki.dwExtraInfo = 0;
SendInput(1, key2, sizeof(INPUT));
key->ki.dwExtraInfo = KEYEVENTF_KEYUP;
SendInput(1, key, sizeof(INPUT));
key2->ki.dwExtraInfo = KEYEVENTF_KEYUP;
SendInput(1, key2, sizeof(INPUT));
//key->ki.dwExtraInfo = KEYEVENTF_KEYUP;
//SendInput(1, key, sizeof(INPUT));
Sleep(500);
}

void _SendInputV2(){
memset(Inputs, 0, sizeof(INPUT));
Inputs[0].type = INPUT_KEYBOARD;
//Inputs[0].ki.wVk = VK_LWIN;
Inputs[0].ki.wVk = 'F';
Inputs[1] = Inputs[0];
Inputs[1].ki.wVk = 'D';
SendInput(2, Inputs, sizeof(INPUT));
//Release WinKey + D
Inputs[0].ki.dwFlags = KEYEVENTF_KEYUP;
Inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(2, Inputs, sizeof(INPUT));
}

如上面code中所示,三个methods分别用来做:

void _SendInput(char ch):接受一个character,并把它发送给当前in focus的窗口,相当于按了一下相对应的键。
void _SendInput():我是想要做出Win+D的show desktop的效果的,这个method和下一个都是这个目的。不过,这个里面,WInKey和D是分别定义的,当然在SendInput() method也是被call了两次。结果是这样子不行,所以有了下面的Version。
void _SendInputV2():这个里面WinKey和D定义在一个INPUT array里面,而SendInput()同样只调用了一次,pass给它的是那个array。这个成功了。

有一点需要注意的是,在SendInput()模拟过Win+D之后要set两个INPUT structure的ki.dwFlags成KEYEVENTF_KEYUP再调用一下这个SendInput(),这样子就release了WinKey+D键了——因为第一次SendInput()时,两个按键是被按着(press)并没有放开(release)的,而改过上面所说的flag后,再一次SendInput()就相当于松开了两个按键。

另外,code中用到的几个function,在MSDN中都有相应的条目。

SendInput Function
FindWindow Function
INPUT Structure
KEYBDINPUT Structure

另外一篇中文的文章“用应用程序模拟键盘和鼠标按键”提到了用Keybd_eventmouse_event这两个function来做同样的事情。这两个function连同上面我用到的几个都是MSDN Library中的,等有时间了我再研究一下它们的异同吧。