?? unix文件模擬系統(tǒng).cpp
字號(hào):
dirnum++;
}
else
{ printf( "<FILE>" ); // 普通文件
filenum++;
}
printf( "\t\t" );
// 顯示讀寫執(zhí)行權(quán)限
for( j = 0; j < 3; j++ )
{ if( di_mode % 2 )
printf( "r" ); // 讀權(quán)限
else
printf( "-" );
di_mode = di_mode / 2;
if( di_mode % 2 ) // 寫權(quán)限
printf( "w" );
else
printf( "-" );
di_mode = di_mode / 2;
if( di_mode % 2 ) // 執(zhí)行權(quán)限
printf( "x" );
else
printf( "-" );
di_mode = di_mode / 2;
}
printf( " %d %d %d %s\n",
// 分別顯示文件主uid,gid,文件大小和文件名
inode->i_uid, inode->i_gid, inode->i_size, dir.direct[i].d_name );
iput( inode );
}
}
printf( "\n %d files\n", filenum); // 顯示文件數(shù)
printf( " %d directories\n", dirnum); // 顯示目錄數(shù)
}
//創(chuàng)建目錄函數(shù):mkdir
void mkdir( char * dirname )
{ int i, dirid, dirpos;
struct inode * inode;
struct dir tempdir;
struct direct buf[BLOCKSIZ / DIRECTSIZ];
unsigned int block;
dirid = namei( dirname );
if( dirid == -1 )
{ printf( "mkdir: cannot make directory '%s': No such file or directory\n", dirname );
return;
}
if( dirid != NULL )
{ printf( "mkdir: cannot make directory '%s': File exists\n", dirname );
return;
}
inode = ialloc();
dirid = inode->i_ino;
if( pre_dinodeid == cur_path_inode->i_ino )
// 如果所要?jiǎng)?chuàng)建的目錄的父目錄為當(dāng)前目錄
{
dirpos = iname( dir, end_path_name );
strcpy( dir.direct[dirpos].d_name, end_path_name );
dir.direct[dirpos].d_ino = dirid;
dir.size++;
}
else // 所要?jiǎng)?chuàng)建的目錄的父目錄不是當(dāng)前目錄
{ tempdir = getdir( pre_dinodeid, " " );
dirpos = iname( tempdir, end_path_name );
strcpy( tempdir.direct[dirpos].d_name, end_path_name );
tempdir.direct[dirpos].d_ino = dirid;
tempdir.size++;
putdir( pre_dinodeid, tempdir );
}
for( i = 0; i < BLOCKSIZ / DIRECTSIZ; i++ ) // 初始化緩沖區(qū)
{ buf[i].d_ino = 0;
strcpy( buf[i].d_name, " " );
}
// 把新建的目錄內(nèi)容寫入緩沖區(qū)
strcpy( buf[0].d_name, ".." );
buf[0].d_ino = pre_dinodeid;
strcpy( buf[1].d_name, "." );
buf[1].d_ino = dirid;
// 寫磁盤i節(jié)點(diǎn)相關(guān)信息
inode->i_size = 2 * DIRECTSIZ;
inode->i_number = 1;
inode->i_mode = DEFAULTMODE | DIDIR;
inode->i_uid = user[user_id].u_uid;
inode->i_gid = user[user_id].u_gid;
block = balloc();
inode->i_addr[0] = block;
//bwrite( block, buf );// 把緩沖區(qū)內(nèi)容寫入新分配的盤塊中
fseek( fd, DATASTART + BLOCKSIZ * block, SEEK_SET );
fwrite( buf , 1, BLOCKSIZ, fd );
iput( inode );
}
// 改變目錄函數(shù):chdir()
void chdir( char * dirname )
{ unsigned int dirid;
char buf[DIRSIZ];
int i, len;
dirid = namei( dirname ); // 獲得當(dāng)前目錄的磁盤i節(jié)點(diǎn)號(hào)
if(( dirid == NULL ) || ( dirid == -1 )) // 沒有該目錄
{ printf( "bash: %s: No such file or directory\n",dirname );
return;
}
len = strlen( dirname );
while( len )
{ i = 0;
while( len )
{
buf[i] = * dirname;
if( buf[i] == '/' )
{
dirname++;
len--;
break;
}
i++;
dirname++;
len--;
}
if( !len )
buf[i] = '\0';
if( buf[0] == '\0' )
{
buf[0] = '/';
buf[1] = '\0';
}
putdir( cur_path_inode->i_ino, dir ); // 把當(dāng)前目錄寫回到磁盤
iput( cur_path_inode );
dir = getdir( dirid, buf ); // 取得所要進(jìn)入的目錄的目錄結(jié)構(gòu)
cur_path_inode = iget( dirid );
if( strcmp( buf, "/" ) == 0 )
cur_dir_id = 0;
else if(strcmp( buf, ".." ) == 0 )
{if( cur_dir_id )
cur_dir_id--;
}
else if( strcmp( buf, "." ) != 0 )
{
cur_dir_id++;
strcpy( cur_direct[cur_dir_id].d_name, buf );
cur_direct[cur_dir_id].d_ino = dirid;
}
}
}
// 刪除目錄函數(shù):rmdir()
void rmdir( char * dirname )
{
int i, dirid;
struct inode * inode;
struct dir tempdir;
struct direct buf[BLOCKSIZ / DIRECTSIZ];
dirid = namei( dirname );
if(( dirid == NULL ) || ( dirid == -1 )) // 找不到該目錄
{ printf( "rmdir: %s: No such file or directory\n", dirname );
return;
}
inode = iget( dirid );
if( !( inode->i_mode & DIDIR )) // 不是目錄
{ printf( "rmdir: %s: is not D irectory,can not delete\n", dirname );
iput( inode );
return;
}
if( !( access( inode ) & WRITE)) // 沒有權(quán)限
{ printf( "bash: %s: Permission denied\n", dirname );
iput( inode );
return;
}
if( inode->i_size > 2 * DIRECTSIZ ) // 目錄非空
{ printf( "rmdir: %s: Directory not empty\n", dirname );
iput( inode );
return;
}
// 初始化緩沖區(qū)
for( i = 0; i < BLOCKSIZ / DIRECTSIZ; i++ )
{ buf[i].d_ino = 0;
strcpy( buf[i].d_name, " " );
}
// 如果刪除的目錄在當(dāng)前目錄下
if( pre_dinodeid == cur_path_inode->i_ino )
{for( i = 0; i < dir.size; i++ )
{ if( dir.direct[i].d_ino == dirid )
break;
}
for( ; i < dir.size - 1; i++ )
{
dir.direct[i].d_ino =dir.direct[i + 1].d_ino;
strcpy(dir.direct[i].d_name , dir.direct[i + 1].d_name);
}
dir.direct[i].d_ino = 0;
strcpy( dir.direct[i].d_name, " " );
dir.size--;
}
else // 刪除的目錄不在當(dāng)前目錄下
{
// 取得所刪除目錄的父目錄
tempdir = getdir( pre_dinodeid, " " );
for( i = 0; i < tempdir.size; i++ ) // 找到所要?jiǎng)h除的目錄
{
if( tempdir.direct[i].d_ino == dirid )
break;
}
for( ; i < tempdir.size - 1; i++ ) // 刪除
{ tempdir.direct[i].d_ino =tempdir.direct[i + 1].d_ino;
strcpy(tempdir.direct[i].d_name ,tempdir.direct[i + 1].d_name);
}
tempdir.direct[i].d_ino = 0; // 清空盤塊號(hào)
strcpy( tempdir.direct[i].d_name, " " ); // 清空目錄名
tempdir.size--; // 父目錄的目錄數(shù)減1
putdir( pre_dinodeid, tempdir ); // 把父目錄寫回磁盤
}
inode->i_number--; // i節(jié)點(diǎn)聯(lián)接計(jì)數(shù)減1
iput( inode );
}
// 獲得指定的目錄內(nèi)容函數(shù):dirgetput()
struct dir getdir( unsigned int dinodeid, char * dirname )
{ struct inode * get_inode;
struct dir dir;
unsigned int i;
get_inode = iget( dinodeid );
if( get_inode->i_mode & DIREG ) // 該文件為普通文件而非目錄文件
{
printf( "bash: %s: 錯(cuò)誤:不是目錄,無法刪除。\n", dirname );
iput( cur_path_inode );
exit(0);
}
// 該用戶沒有相應(yīng)的權(quán)限,不能進(jìn)入
if( !access( get_inode )
&& dinodeid != ROOTDIR )
{
printf( "bash: %s: Permission denied\n", dirname );
iput( get_inode );
exit(0);
}
dir.size = get_inode->i_size / DIRECTSIZ;
for( i = 0; i < DIRNUM; i++ )
{
strcpy( dir.direct[i].d_name, " " );
dir.direct[i].d_ino = DIEMPTY;
}
// 讀盤塊內(nèi)容
for( i = 0; i < dir.size / ( BLOCKSIZ / DIRECTSIZ ) + 1; i++ )
{fseek( fd, DATASTART + BLOCKSIZ * get_inode->i_addr[i], SEEK_SET );
fwrite( &dir.direct[( BLOCKSIZ / DIRECTSIZ ) * i] , 1, BLOCKSIZ, fd );
}
iput( get_inode );
return dir;
}
void putdir( unsigned int dinodeid, struct dir dir) // 把目錄內(nèi)容回寫到盤塊函數(shù)
{ struct inode * inode;
unsigned int block;
int i;
inode = iget( dinodeid );
for( i = 0; i < inode->i_size / BLOCKSIZ + 1; i++ )
bfree( inode->i_addr[i] );
for( i = 0; i < dir.size; i += BLOCKSIZ / DIRECTSIZ)
{
block = balloc();
inode->i_addr[i] = block;
fseek( fd, DATASTART + BLOCKSIZ * block, SEEK_SET );
fwrite(&dir.direct[i] , 1, BLOCKSIZ, fd );
}
inode->i_size = dir.size * DIRECTSIZ;
iput( inode );
}
int format() //命令format.c
{
struct inode * inode;
struct user tempuser[USERNUM];
struct dinode dinode_buf;
struct direct dir_buf[BLOCKSIZ / DIRECTSIZ];
unsigned int block_buf1[BLOCKSIZ / sizeof( int )];
char * buf;
int i, j;
fd = tmpfile(); // 建立文件
buf = (char * )malloc( 1024*1024 ); // 申請(qǐng)1M空間
if( buf == NULL ) // 申請(qǐng)不成功,返回
{
printf( "\nThe system file can't be create!\n" );
return 0;
}
fseek( fd, 0, SEEK_SET );
fwrite( buf, 1, 1024*1024, fd );
free ( buf ); // 設(shè)置磁盤i節(jié)點(diǎn)緩沖區(qū),DIEMPTY表示空閑
dinode_buf.di_mode = DIEMPTY;
fseek( fd, DINODESTART, SEEK_SET );
for( i = 0; i < DINODEBLK * BLOCKSIZ / DINODESIZ; i++ )
{
fseek( fd, DINODESTART + DINODESIZ * i, SEEK_SET );
fwrite( &dinode_buf, 1, sizeof( dinode_buf ), fd );
}
inode = iget( 0 ); // 0#磁盤i節(jié)點(diǎn)不用
inode->i_mode = DIEMPTY;
iput( inode );
inode = iget( 1 ); // 1#放用戶名表
inode->i_number = 1;
inode->i_mode = DIREG;
inode->i_size = sizeof( struct user ) * USERNUM;
inode->i_addr[0] = 1;
// 用戶imacih是超級(jí)用戶
strcpy( tempuser[0].u_name, "user" );
strcpy( tempuser[0].password, "password" );
tempuser[0].u_default_mode = SUPERMODE; // 超級(jí)用戶
tempuser[0].u_gid = 1;
tempuser[0].u_uid = 1;
for( i = 1; i < USERNUM; i++ )
{
strcpy( tempuser[i].u_name, " " );
tempuser[i].u_uid = 0;
}
fseek( fd, DATASTART + BLOCKSIZ * inode->i_addr[0], SEEK_SET );
fwrite( tempuser, 1, inode->i_size, fd );
iput( inode );
inode = iget( 2 ); // 2#用于存儲(chǔ)根目錄
inode->i_number = 1;
inode->i_mode = DEFAULTMODE | DIDIR;
inode->i_size = 2 * DIRECTSIZ;
inode->i_addr[0] = 2;
strcpy( dir_buf[0].d_name, ".." );
dir_buf[0].d_ino = 2;
strcpy( dir_buf[1].d_name, "." );
dir_buf[1].d_ino = 2;
fseek( fd, DATASTART + BLOCKSIZ * inode->i_addr[0], SEEK_SET );
fwrite( dir_buf, 1, inode->i_size, fd );
iput( inode );
// 初始化超級(jí)塊
filsys.s_ninode = DINODEBLK * BLOCKSIZ / DINODESIZ - 3; // 空閑磁盤i節(jié)點(diǎn)數(shù)
filsys.s_nfree = FILEBLK - 3; // 空閑文件塊數(shù)
// 初始化空閑磁盤i節(jié)點(diǎn)堆棧
for( i = 0; i < NICINOD; i++ )
{
filsys.s_inode[i] = 3 + i; // 從3#起空閑,前面3個(gè)已用
}
filsys.s_pinode = 0; // 當(dāng)前空閑磁盤i節(jié)點(diǎn)指針
filsys.s_rinode = NICINOD + 3; // 下一準(zhǔn)備裝入空閑i節(jié)點(diǎn)棧的i節(jié)點(diǎn)號(hào)
// 初始化空閑盤塊堆棧
// 把第1組空閑盤塊放進(jìn)空閑盤塊堆棧
for( i = 0; i < NICFREE; i++ )
filsys.s_free[i] = 3 + NICFREE - 1 - i;
filsys.s_pfree = NICFREE - 1; // 當(dāng)前空閑盤塊堆棧指針
for( i = 3 + NICFREE * 2 - 1; i < FILEBLK; i += NICFREE )
{
for( j = 0; j < NICFREE; j++ )
{
// 往緩沖區(qū)寫與成組鏈接法組織空閑盤塊有關(guān)的信息:下一組盤塊空閑塊號(hào)與塊數(shù)
block_buf1[j] = i - j;
}
block_buf1[NICFREE] = NICFREE; // 該項(xiàng)記錄本組的空閑盤塊數(shù)
// 把緩沖區(qū)內(nèi)容寫到每組空閑盤塊的最后一塊中
fseek( fd, DATASTART + BLOCKSIZ * (i - NICFREE), SEEK_SET );
fwrite(block_buf1, 1, BLOCKSIZ, fd );
}
// 最后一組空閑盤塊可能不足NICFREE塊,故需單獨(dú)處理
i = i - NICFREE;
for( j = 0; j < FILEBLK - i + 1; j++ )
block_buf1[j] = FILEBLK - j;
block_buf1[NICFREE] = FILEBLK - i + 1; // 最末組的空閑盤塊數(shù)
fseek( fd, DATASTART + BLOCKSIZ * i, SEEK_SET );
fwrite(block_buf1, 1, BLOCKSIZ, fd );
// 把超級(jí)塊寫入 block 1#
fseek( fd, BLOCKSIZ, SEEK_SET );
fwrite( &filsys, 1, sizeof( struct filsys ), fd );
return 1;
}
// 系統(tǒng)終止函數(shù):halt()
void halt()
{// struct inode * inode;
int i,j;
// 保存當(dāng)前目錄
putdir(cur_path_inode->i_ino, dir);
// 釋放所有用戶打開表和系統(tǒng)打開表
for( i = 0; i < USERNUM; i++ )
if( user[i].u_uid != 0 )
for( j = 0; j < NOFILE; j++ )
if( user[i].u_ofile[j] != SYSOPENFILE + 1 )
close( j );
// 保存超級(jí)塊信息
fclose( fd );// 關(guān)閉文件,臨時(shí)文件自動(dòng)刪除
printf( "Good bye! See you next time.\n" );
}
// 分配空閑磁盤i節(jié)點(diǎn)函數(shù)iallfre()
static struct dinode block_buf2[BLOCKSIZ / DINODESIZ];
struct inode * ialloc()
{ struct inode * temp_inode;
unsigned int cur_di;
int i;
if( filsys.s_ninode == 0 ) // 沒有空閑磁盤i節(jié)點(diǎn)
{ printf( "No leisure dinode!\n" );
return NULL;
}
{ cur_di = filsys.s_rinode;
if( filsys.s_ninode >= NICINOD )
// 空閑磁盤i節(jié)點(diǎn)數(shù)可裝滿空閑i節(jié)點(diǎn)棧
{
filsys.s_pinode = 0;
// 把下一組磁盤i節(jié)點(diǎn)讀進(jìn)空閑磁盤i節(jié)點(diǎn)棧
while( filsys.s_pinode < NICINOD )
{
fseek (fd, DINODESTART + cur_di * DINODESIZ, SEEK_SET);
fread (block_buf2, 1, BLOCKSIZ, fd);
for( i = 0; ( i < BLOCKSIZ / DINODESIZ ) && ( filsys.s_pinode < NICINOD ); )
{
if( block_buf2[i].di_mode == DIEMPTY ) // 該磁盤i節(jié)點(diǎn)空閑
{
filsys.s_inode[filsys.s_pinode] = cur_di; // 把該i節(jié)點(diǎn)裝入空閑棧
filsys.s_pinode++; // 棧指針下移一位
}
i++, cur_di++;
}
}
filsys.s_pinode = 0; // 置空閑i節(jié)點(diǎn)指針為0
}
else // 剩下的空閑磁盤i節(jié)點(diǎn)不能裝滿棧區(qū)
{
// 計(jì)算出空閑棧指針裝入i節(jié)點(diǎn)的第一個(gè)位置
filsys.s_pinode = NICINOD - filsys.s_ninode;
while( filsys.s_pinode < NICINOD )
{
fseek( fd, DINODESTART + cur_di * DINODESIZ, SEEK_SET );
fread( block_buf2, 1, BLOCKSIZ, fd );
for( i = 0; ( i < BLOCKSIZ / DINODESIZ ) && ( filsys.s_pinode < filsys.s_ninode ); )
{
if( block_buf2[i].di_mode==DIEMPTY )
{
filsys.s_inode[filsys.s_pinode] = cur_di;
filsys.s_pinode++;
}
i++, cur_di++;
}
}
filsys.s_pinode = NICINOD - filsys.s_ninode;
}
}
// 分配內(nèi)存i節(jié)點(diǎn)
temp_inode = iget( filsys.s_inode[filsys.s_pinode] );
// 從磁盤i節(jié)點(diǎn)讀取數(shù)據(jù)到內(nèi)存i節(jié)點(diǎn)
fseek( fd, DINODESTART + filsys.s_inode[filsys.s_pinode] * DINODESIZ, SEEK_SET );
fwrite( &temp_inode->i_number, 1, sizeof(struct dinode), fd );
filsys.s_pinode++; // 棧指針下移一位
filsys.s_ninode--; // 空閑磁盤i節(jié)點(diǎn)又少了一個(gè)
return temp_inode;
}
// 回收磁盤i節(jié)點(diǎn)函數(shù)
void ifree(unsigned int dinodeid)
{
filsys.s_ninode++; // 空閑磁盤i節(jié)點(diǎn)加1
if( filsys.s_pinode != 0 ) // 空閑磁盤i節(jié)點(diǎn)棧未滿
{
// 直接回收
filsys.s_pinode--;
filsys.s_inode[filsys.s_pinode] = dinodeid;
}
else // 空閑磁盤i節(jié)點(diǎn)棧已滿
{
if( dinodeid < filsys.s_rinode ) // 磁盤i節(jié)點(diǎn)號(hào)小于銘記i節(jié)點(diǎn)號(hào)
{
filsys.s_inode[0] = dinodeid; // 回收
filsys.s_rinode = dinodeid;
// 把新回收的i節(jié)點(diǎn)作為銘記i節(jié)點(diǎn)
}
}
}
// 內(nèi)存i節(jié)點(diǎn)分配函數(shù):igetput
struct inode * iget( unsigned int dinodeid )
{ int inodeid;
long addr;
struct inode * temp, * newinode;
inodeid = dinodeid % NHINO; // 用Hash查找法查找內(nèi)存i節(jié)點(diǎn)時(shí)用
// 用Hash法查找內(nèi)存i節(jié)點(diǎn)
for( temp = hinode[inodeid].i_forw; temp != NULL; temp = temp->i_forw )
{ if( temp->i_ino == dinodeid ) // 該文件已被打開
{ temp->i_count++; // 引用計(jì)數(shù)加1
return temp; // 可以退出
}
}
// 文件還沒有被打開,以下步驟為之分配內(nèi)存i節(jié)點(diǎn)
// 1. 計(jì)算該文件的磁盤i節(jié)點(diǎn)所在實(shí)際地址
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -