posted @ 2007-10-17 21:06 謝龍飛 閱讀(205) | 評論 (0) | 編輯 收藏
一個進程的 effective user ID 是指此進程目前實際有效的用戶 ID(也就是權限的大小),effective user ID 主要用來校驗權限時使用,比如打開文件、創建文件、修改文件、kill 別的進程,等等。
如果一個進程是以 root 身份來運行的,那么上面這兩個 ID 可以用 setuid/seteuid 隨便修改,想怎么改就怎么改,改來改去都可以。
但是如果一個進程是以普通用戶身份來運行的,那么上面這兩個 ID 一般來說是相同的,并且也不能隨便修改。只有一種情況例外:此進程的可執行文件的權限標記中,設置了“設置用戶 ID”位!
在命令行中,設置一個可執行文件的“設置用戶 ID”位的最簡單的方法,就是用
chmod +s /path/to/file
這個命令。
一旦用了這個命令之后,再執行這個文件,
那么生成的進程的 effective user ID 就變成了這個可執行文件的 owner user ID(屬主用戶 ID),
而 real user ID 仍然是啟動這個程序時所用的用戶的 ID。
打個比方來說,如果有這樣的一個文件:
引用:-rw[color=red]s[/color]r-[color=red]s[/color]r-x 1 susesuse susesuse 7902 2006-08-31 13:22 tuid
注意這個文件已經用 chmod +s 命令設置過“設置用戶 ID”位了。
然后我用 flw 這個用戶來執行它,那么生成的進程它的 real user ID 就是 flw(因為我是用 flw 運行的),但是 effective user ID 就變成了 susesuse(因為這個可執行文件被設置了“設置用戶 ID”位,并且它的 owner user ID 是 susesuse)。
這時,這個進程實際上就有兩個用戶權限了。只不過目前生效的是 susesuse,因此它目前能夠且只能夠操作 susesuse 用戶的文件,如果現在我又想要操作 flw 用戶的文件怎么辦?
很簡單,只需要 seteuid( getuid() ) 就可以了。執行完這句之后,effective user ID 就變成和 real user ID 一樣了,都變成 flw 了。
可是如果過了一會兒我又想要變回來怎么辦?因為 effective user ID 和 real user ID 此時都變成了 flw 了,所以操作系統必須得有一個地方保存住原來的“設置用戶 ID”(也就是可執行文件的 owner user ID),不然等你再想要 seteuid 的時候,操作系統就不知道你有沒有那個權利了。(總不能再去訪問一次文件系統吧?那樣也太沒有效率了)
操作系統為了能夠在設置了 seteuid 之后,再次設置回來,所以特地將原來的“設置用戶 ID”保存下來了,這個保存下來的設置用戶 ID 自然就叫做“保存的設置用戶 ID”。
下面看一段寫的例子程序:
flw@Sleeper:~$ whoami
flw
flw@Sleeper:~$ cat tuid.c
# include <stdio.h>
# include <sys/types.h>
# include <pwd.h>
int main( void )
{
struct passwd *pwd;
pwd = getpwuid( geteuid() );
printf( "effective UID: [%s]\n", pwd->pw_name );
system( "touch /tmp/foo.txt; ls -l /tmp/foo.txt; rm -rf /tmp/foo.txt" );
printf( "\nset EUID to `flw'..\n" );
pwd = getpwnam( "flw" );
seteuid(pwd->pw_uid);
pwd = getpwuid( geteuid() );
printf( "effective UID: [%s]\n", pwd->pw_name );
system( "touch /tmp/foo.txt; ls -l /tmp/foo.txt; rm -rf /tmp/foo.txt" );
printf( "\nset EUID to `root'..\n" );
seteuid(0);
pwd = getpwuid( geteuid() );
printf( "effective UID: [%s]\n", pwd->pw_name );
system( "touch /tmp/foo.txt; ls -l /tmp/foo.txt; rm -rf /tmp/foo.txt" );
return 0;
}
flw@Sleeper:~$ su root -c "cc -o tuid tuid.c; chmod +s tuid; ls -al tuid"
Password:
-rwsr-sr-x 1 root root 7902 2006-08-31 13:55 tuid
flw@Sleeper:~$ ./tuid
effective UID: [root]
-rw-r--r-- 1 root root 0 2006-08-31 13:55 /tmp/foo.txt
set EUID to `flw'..
effective UID: [flw]
-rw-r--r-- 1 flw root 0 2006-08-31 13:55 /tmp/foo.txt
set EUID to `root'..
effective UID: [root]
-rw-r--r-- 1 root root 0 2006-08-31 13:55 /tmp/foo.txt
flw@Sleeper:~$
posted @ 2007-10-15 23:05 謝龍飛 閱讀(1122) | 評論 (0) | 編輯 收藏
今天 調試一個020的數據處理程序碰到了一個問題,雖然已經解決,但是還是有點不明白,先記錄在這里,以后有空的時候再好好 細細地想一下
我的原代碼如下:
#include <C8051f020.h>
#define SYS_CLK 22118400
typedef struct //存儲結構體
{
unsigned char AD[93]; //2543的AD數據
unsigned char shi; //gprs的數據
unsigned char fen;
unsigned char miao;
unsigned long jingdu_zheng;
unsigned long jingdu_xiao;
unsigned long weidu_zheng;
unsigned long weidu_xiao;
unsigned char sudu_zheng;
unsigned char sudu_xiao;
}ram;
typedef struct //定義一個存儲地址結構體
{
unsigned char adr_suocun; //鎖存的8位地址
unsigned char dptr_gao; //dptr
unsigned char dptr_di;
}ADR_struct;
void sysclk_Init(void);
void dog_Init(void);
void port_Init(void);
void cunchu_Init(void);
void cunchu_Init1(void);
void ram_init(unsigned char ADR);
void save_struct(ram a);
ram read_struct(void);
sbit AHH = P1^0; //用通用I/O來控制訪問地址
sbit LB = P1^1;
sbit UB = P1^2;
sbit ALE = P0^5;
ADR_struct dui_shou; //存儲隊首地址
ADR_struct dui_wei; //存儲隊尾地址
void main()
{
unsigned char i;
ram a;
sysclk_Init();
dog_Init();
cunchu_Init();
port_Init();
UB = 1;
LB = 0;
dui_wei.adr_suocun=0; //鎖存的8位地址
dui_wei.dptr_gao=0x08; //dptr
dui_wei.dptr_di=0;
for(i=0;i<93;i++)
a.AD[i]=i;
a.shi = 2;
a.fen = 2;
a.miao= 2;
a.jingdu_zheng= 2;
a.jingdu_xiao=2;
a.weidu_zheng=2;
a.weidu_xiao=2;
a.sudu_zheng=2;
a.sudu_xiao=2;
for(i=0;i<17;i++)
save_struct(a);
}
void ram_init(unsigned char ADR) //ADR為要鎖存的A8-A15 LU_B為 字節高低選擇位為0 輸出抵字節位 為1輸出高字節位
{
unsigned char i;
AHH = 1;
for(i=0;i<50;i++); //等待穩定
P3 = ADR; //ADR為全局變量 選擇存儲塊
for(i=0;i<50;i++); //等待穩定
AHH = 0; //注意 每一個LU_B ADR組合 對應4K的地址空間 每次換“塊”的時候均需先調用此函數
}
void save_struct(ram a) //將a存儲到FIFO 隊尾
{
ram xdata *p;
unsigned int i;
cunchu_Init();
ram_init(dui_wei.adr_suocun); //按隊尾地址結構體中的suocun初始化sram
dui_wei.dptr_gao<<=8;
p = dui_wei.dptr_gao+dui_wei.dptr_di;
*p = a; //存儲a到隊尾
//以下代碼為隊尾地址變換
if((dui_wei.dptr_di==0x91)&&(dui_wei.dptr_gao==0x17)&&(dui_wei.adr_suocun==0xff)&&(UB ==0))
//存儲空間已經用完 地址循環至最低地址
{ //此時最后一塊內存 剛好存儲1937個字節
dui_wei.dptr_gao = 0x08; //dptr_di==1001 0001 dptr_gao==&&000 10 111
dui_wei.dptr_di = 0x00; //suocun已經滿ff UB為有效
dui_wei.adr_suocun = 0;
UB = !UB;
LB = !LB;
}
else
{
if((dui_wei.dptr_gao<<8)+dui_wei.dptr_di<=(1937-114)) //2k空間最多只能存儲17幀即:1937個字節
{
p=(dui_wei.dptr_gao<<8)+dui_wei.dptr_di+114; //每幀數據長114個字節 dptr值加上114;
dui_wei.dptr_di = (unsigned char)p;
i = p;
dui_wei.dptr_gao =i>>8;
}
else //2k空間已經用完dptr=1937=0000111 10010001時 移動到下一個2k塊 切換
{
if(dui_wei.dptr_gao==0x0f) //將高八位從000 01 111 切換成 000 10 000 低八位全清零
{
dui_wei.dptr_di=0;
dui_wei.dptr_gao ^=0x1f;
}
else if(dui_wei.dptr_gao==0x17) //將高八位從000 10 111 切換成 000 01 000 低八位全清零
{ //并觸發adr_suocun + 1
dui_wei.dptr_di=0;
dui_wei.dptr_gao ^=0x1f;
//以下為adr_suocun + 1處理代碼
if(dui_wei.adr_suocun==0xff) //adr_suocun + 1過程中 要判斷是否需要切換高低字節 用完低字節后 再用高字節
{
LB = !LB;
UB = !UB;
dui_wei.dptr_di = 0;
dui_wei.dptr_gao = 0x08; //將高八位切換成000 01 000 低八位清零
dui_wei.adr_suocun=0;
}
else //未用完 不切換
{
dui_wei.dptr_di = 0; //將高八位切換成000 01 000 低八位清零
dui_wei.dptr_gao = 0x08;
dui_wei.adr_suocun++;
}
}
/* if(dui_wei==dui_shou) //如果存儲速度大于讀取速度 則覆蓋最舊的數據
{ //使得隊首 向后移動一個 幀 從而丟棄最舊的數據幀
adr_add_change;
}*/
}
}
}
void sysclk_Init(void) //系統時鐘初始化
{
int i;
OSCXCN = 0x67; //啟動外部11.0592MHz震蕩器
for(i = 0;i<255;i++); //等待外部晶體起振
while((OSCXCN & 0x80)==0x00); //查詢標志位 以判斷外部時鐘是否穩定
OSCICN = 0x88; //使用外部震蕩器做系統時鐘并使能時鐘丟失檢測
CKCON = 0x10; //初始化T1時鐘為系統時鐘
}
void dog_Init(void) //看門狗設置為:關閉
{
EA = 0;
WDTCN = 0xde;
WDTCN = 0xad;
EA = 1;
}
void port_Init(void) //端口分配與輸入輸出方式
{
XBR2 = 0x44; //使能交叉開關和全局弱上拉 配置UART1引腳,外部存儲器接口配置到低端口
XBR0 = 0x04; //配置UARTO引腳
XBR1 = 0x00;
P0MDOUT = 0xf5; //UART的RX引腳總被配置成開漏輸出 TX引腳為推拉輸出 RD WR ALE 2543EOC均為推拉輸出
P3MDOUT = 0xff; //DT0-DT7
}
void cunchu_Init(void)
{
EMI0CF = 0x0c; //配置外部存儲器為復用方式 只使用片外XRAM ALE脈寬為一個系統時鐘周期
EMI0TC = 0x6d; //配置外部存儲器的接口時序
}
void cunchu_Init1(void)
{
EMI0CF = 0x10;
EMI0TC = 0x6d;
}
segment does not fit
剛開始知道是內部ram超限了
但是將 ram a 改成 xdata ram a
還是有問題
直到再將 全局變量
ADR_struct dui_shou; //存儲隊首地址
ADR_struct dui_wei; //存儲隊尾地址
改成
ADR_struct idata dui_shou; //存儲隊首地址
ADR_struct idata dui_wei; //存儲隊尾地址
才解決錯誤
有時間好好考慮下 感覺 全局變量 是個關鍵
posted @ 2007-10-08 16:46 謝龍飛 閱讀(360) | 評論 (0) | 編輯 收藏
tar -I或者bunzip2命令都可以解壓.bz2文件
tar xvfj example.tar.bz2
tar xvfz example.tar.gz
tar xvfz example.tgz
tar xvf example.tar
unzip example.zip
tar -jvxf some.bz,就是把tar的zvxf 改成jvxf
zip/tar rh8下有一個圖形界面的軟件file-roller可以做這件事。另外可以用unzip *.zip解開zip文件,unrar *.rar解開rar文件,不過unrar一般系統不自帶,要到網上下載。
# rpm2cpio example.rpm │ cpio -div
# ar p example.deb data.tar.gz | tar zxf -
Alien
提供了.tgz, .rpm, .slp和.deb等壓縮格式之間的相互轉換: sourceforge.net/projects/alien
sEx提供了幾乎所有可見的壓縮格式的解壓接口:sourceforge.net/projects/sex 0058
在多級目錄中查找某個文件的方法(青海湖)
find /dir -name filename.ext
du -a | grep filename.ext
locate filename.ext
posted @ 2007-10-02 20:22 謝龍飛 閱讀(269) | 評論 (0) | 編輯 收藏
Linux下軟件安裝方法總結
關鍵詞: Linux tar 安裝軟件 rpm apt
Linux下軟件安裝方法總結:
一、rpm包安裝方式步驟:
1、找到相應的軟件包,比如soft.version.rpm,下載到本機某個目錄;
2、打開一個終端,su -成root用戶;
3、cd soft.version.rpm所在的目錄;
4、輸入rpm -ivh soft.version.rpm
二、deb包安裝方式步驟:
1、找到相應的軟件包,比如soft.version.deb,下載到本機某個目錄;
2、打開一個終端,su -成root用戶;
3、cd soft.version.deb所在的目錄;
4、輸入dpkg -i soft.version.deb
三、tar.gz源代碼包安裝方式:
1、找到相應的軟件包,比如soft.tar.gz,下載到本機某個目錄;
2、打開一個終端,su -成root用戶;
3、cd soft.tar.gz所在的目錄;
4、tar -xzvf soft.tar.gz //一般會生成一個soft目錄
5、cd soft
6、./configure
7、make
8、make install
四、tar.bz2源代碼包安裝方式:
1、找到相應的軟件包,比如soft.tar.bz2,下載到本機某個目錄;
2、打開一個終端,su -成root用戶;
3、cd soft.tar.bz2所在的目錄;
4、tar -xjvf soft.tar.bz2 //一般會生成一個soft目錄
5、cd soft
6、./configure
7、make
8、make install
五、apt方式安裝:
1、打開一個終端,su -成root用戶;
2、apt-cache search soft 注:soft是你要找的軟件的名稱或相關信息
3、如果2中找到了軟件soft.version,則用apt-get install soft.version命令安裝軟件 注:只要你可以上網,只需要用apt-cache search查找軟件,用apt-get install軟件
六、bin文件安裝:
如果你下載到的軟件名是soft.bin,一般情況下是個可執行文件,安裝方法如下:
1、打開一個終端,su -成root用戶;
2、chmod +x soft.bin
3、./soft.bin //運行這個命令就可以安裝軟件了
/************關于本文檔********************************************
*filename:Linux下軟件安裝方法總結
*purpose:總結了Linux下各種軟件安裝方法
*wrote by: zhoulifa(zhoulifa@163.com) 周立發(http://zhoulifa.bokee.com)
Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言編程
*date time:2006-07-26 18:10:00
*Note: 任何人可以任意復制代碼并運用這些文檔,當然包括你的商業用途
* 但請遵循GPL。
*Hope:希望越來越多的人貢獻自己的力量,為科學技術發展出力
*********************************************************************/
七、不需要安裝的軟件:
有了些軟件,比如lumaqq,是不需要安裝的,自帶jre解壓縮后可直接運行。假設下載的是lumaqq.tar.gz,使用方法如下:
1、打開一個終端,su -成root用戶;
2、tar -xzvf lumaqq.tar.gz //這一步會生成一個叫LumaQQ的目錄
3、cd LumaQQ
4、chmod +x lumaqq //設置lumaqq這個程序文件為可運行
5、此時就可以運行lumaqq了,用命令./lumaqq即可,但每次運行要輸入全路徑或切換到剛才生成的LumaQQ目錄里
6、為了保證不設置路徑就可以用,你可以在/bin目錄下建立一個lumaqq的鏈接,用命令ln -s lumaqq /bin/ 即可,以后任何時候打開一個終端輸入lumaqq就可以啟動QQ聊天軟件了
7、
如果你要想lumaqq有個菜單項,使用菜單編輯工具,比如Alacarte Menu
Editor,找到上面生成的LumaQQ目錄里的lumaqq設置一個菜單項就可以了,當然你也可以直接到
/usr/share/applications目錄,按照里面其它*.desktop文件的格式生成一個自己的desktop文件即可。
建議開發者們不要用red hat/red
flag/suse等第一代Linux操作系統,用這些除了方便(也就是說比較傻瓜型)、界面豪華點外沒什么好。用debian/ubuntu等第二代
吧,apt命令安裝軟件是最簡單的。apt命令會自動解決軟件安裝過程中的依賴問題,會把沒有的包安裝上,會把版本低的包自動升級,當然,都是要經你確認
一次的。
如果你使用Red Hat等第1代Linux系統,安裝軟件是比較麻煩的事,rpm -ivh
softA.rpm是用來安裝softA軟件的,但通常情況下可能遇到的問題是提示說需要安裝softB1, softB2,
softB3等一堆軟件,然后你安裝softB1軟件包時,可能又會提示你說需要安裝softC1, softC2, softC3,
softC4等一堆軟件……這樣一來你就只夠時間到處去找這些軟件包了。光盤上沒有就得去網上下載,網上還得搜索半天,時間都花在搜索軟件包了。而且就算
找到這些軟件包,還可能會遇到的問題是:softC2軟件包必須在softC1軟件包之前安裝才可以,順序錯了也安裝不成功。但這誰知道呢?難啊。所以,
你沒有時間來安裝體驗軟件的功能了,更別說開發軟件了。
建議你安裝第2代Linux操作系統,典型的是Debian Linux和Ubuntu Linux,我之前在文章“如何在安裝了Windows操作系統的電腦上安裝Linux操作系統”里提到一個簡明安裝手冊,你下載來照著操作就可以安裝Ubuntu了。
第2代操作系統在安裝軟件方面相當簡單:第一步,搜索你要的軟件,比如你要找一個游戲軟件,它的名稱叫myward,這個游戲軟件的說明是:my
own war game。搜索這個軟件包就只需要輸入命令apt-cache search
myward,或者輸入軟件名稱的一部分apt-cache search
war,或者你不知道軟件名稱,輸入軟件說明里的一部分文字apt-cache search
game,都可以找到這個軟件,找到后進行第二步,只需要輸入apt-get install myward,即后面跟上軟件名稱就可以安裝了。
posted @ 2007-09-30 21:50 謝龍飛 閱讀(228) | 評論 (0) | 編輯 收藏