头文件:
#ifndef MYSYSTEM_H_INCLUDED
#define MYSYSTEM_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
//#include<conio.h>
#include<string.h>
#include <malloc.h>
int EFFECTCOUNT = 0;
char PROCUSER[10][20];
struct inode{
struct inode *i_forw; //前面的链接节点
struct inode *i_back; //后面的链接节点
struct inode *downdir; //陷入节点
char I_flag; //节点类型
unsigned short di_number; //关联文件数,当为0时,则删除该文件
unsigned int di_mode; //存取权限
unsigned short di_uid; //磁盘i节点用户
char name[20];
struct file *f; //文件指针
};
struct file{
char content[1000];
int file_size;
};
struct userapass{
int uid;
char password[20];
char username[20];
};
struct current_u{
struct userapass *cp; //当前用户
struct current_u *np; //下一个用户
struct current_u *lp; //上一个用户
};
struct inode *STACKINODE[20];
int STACTINODETOP=0;
#endif // MYSYSTEM_H_INCLUDED
主程序:
#include"mysystem.h"
#define PAUSE printf("Press Enter key to continue..."); fgetc(stdin);
struct current_u cu; //当前用户
struct userapass *uspa; //创建用户指针
struct current_u *genUser; //指向第一个用户的指针
struct inode *node; //当前节点
struct inode *nextnode; //下一个节点
struct inode *genNode; //保存根节点
struct inode *currentGenNode; //保存当前路径的根节点
struct inode *theLastNode; //最后一个保存的节点
char CURRENTUSER[20]; //当前用户名字
int CURRENTUSERUID = 0; //当前用户的uid
char CURRENTDIR[100]; //当前目录
struct file *myfile; //文件指针
void createRoot() //创建root用户
{
char pwd[20];
char ch;
char p[20];
uspa = (struct userapass *)malloc(sizeof(struct userapass)); //动态创建用户信息
cu.lp = NULL;
cu.np = NULL;
uspa->uid = 0;
strcpy(uspa->username,"root");
printf("Welcome to my System!\n");
printf("First,Let's create root user to use my system!\n");
printf("Attention!This user has all privileges,using it carefully!\n");
printf("Input password twice!\n");
/*while((ch=getchar())!='\n')//判断是否是回车
//while(1)
{
// system("stty -echo");
// ch = getchar();
// if(ch == '\r'){
//system("stty echo");
// break;
// }
// system("stty echo");
if(ch==8)//实现backspace键的功能,其中backspace键的ascii码是8
{
//putchar('\b');
//putchar('\b');
//putchar('\b');
if(p>0){//最多只能删到没有字符
p--;
putchar('\b');
putchar(' '); //替换*字符
putchar('\b');
}else{
putchar(' ');
putchar('\b');
}
continue;
}
else
putchar('*');//在屏幕上打印星号
pwd[p++]=ch;//保存密码
}
pwd[p] = '\0';*/
while(1)
{
printf("Input password 1:");
system("stty -echo");
gets(pwd);
system("stty echo");
printf("\n");
printf("Input password 2:");
system("stty -echo");
gets(p);
system("stty echo");
printf("\n");
if(strcmp(pwd,p) == 0)
break;
else
printf("Input password error,please input again!\n");
}
strcpy(uspa->password,pwd);
cu.cp = uspa;
printf("\n");
//puts(uspa->password);
printf("OK,Let's start!\n");
EFFECTCOUNT += 1;
strcpy(PROCUSER[0],"root");
//system("pause");
PAUSE
system("clear");
}
void login() //登录账户
{
char username[20];
char password[20];
int p = 0 ;
char ch;
int count = 0;
struct current_u *log;
struct current_u *nextlog;
log = &cu;
nextlog = cu.np;
printf("Username:");
gets(username);
while( log != NULL )
{
if( strcmp(log->cp->username,username) == 0 )
break;
else
{
log = nextlog;
if( nextlog != NULL )
nextlog = nextlog->np;
}
}
if( log == NULL )
{
printf("Don't have the user!");
exit(-1);
}
while( count < 3) //三次机会输入密码
{
/* printf("Password:");
//while((ch = getch()) != '\r')
while(1)
{
system("stty -echo");
ch = getchar();
if(ch == '\r'){
system("stty echo");
break;
}
system("stty echo");
password[p++] = ch;
if( ch == 8 && p > 0)
p--;
}
password[p] = '\0';*/
printf("Input password:");
system("stty -echo");
gets(password);
system("stty echo");
//printf("\n");
//printf("Input password 2:");
//system("stty -echo");
//gets(p);
//system("stty echo");
//printf("\n");
//if(strcmp(pwd,p) == 0)
// break;
//else
// printf("Input password error,please input again!\n");
if(strcmp(password,log->cp->password) == 0 )
break;
count++;
putchar('\n');
printf("You have wrong %d times,three times wrong you will exit!\n",count);
p = 0;
//printf("%d\n",strlen(password));
//puts(password);
}
if( count == 3 )
exit(-2);
printf("\nLog successfully!Welcome %s\n",log->cp->username);
strcpy(CURRENTUSER,log->cp->username);
//system("pause");
PAUSE
}
void showMenu()
{
system("clear");
printf("*****************************************************************************\n");
printf("*This is an imitative Linux System!Bellow is the function which we support *\n");
printf("* ls *\n");
printf("* ll *\n");
printf("* cd *\n");
printf("* chmod *\n");
printf("* pwd *\n");
printf("* useradd *\n");
printf("* cat *\n");
printf("* vim *\n");
printf("* touch *\n");
printf("* su *\n");
printf("* exit *\n");
printf("* rm *\n");
printf("* uv *\n");
printf("* mkdir *\n");
printf("*****************************************************************************\n");
}
void mkdir(char *dirname, struct inode *nn, int modeNum)
{
nextnode = (struct inode *)malloc(sizeof(struct inode));
nn->i_back = nextnode;
nextnode->di_mode = modeNum;
nextnode->i_forw = nn;
nextnode->di_uid = 0;
nextnode->di_number = 1;
nextnode->I_flag = 'd';
nextnode->i_back = NULL;
nextnode->downdir = NULL;
strcpy(nextnode->name,dirname);
}
void initialNode()
{
node = (struct inode *)malloc(sizeof(struct inode));
node->i_forw = NULL; //初始化,根目录前面没有节点
node->i_back = NULL; //初始化,根目录后面没有节点
node->di_mode = 777; //权限777
node->di_uid = 0; //所属用户
node->di_number = 1; //可访问
node->I_flag = 'd'; //节点类型,目录
strcpy(node->name, "/"); //目录名
strcat(CURRENTDIR,"/");
genNode = node;
mkdir("etc",node,777);
node = nextnode;
mkdir("dev",node,777);
node = nextnode;
mkdir("home",node,777);
node = nextnode;
mkdir("media",node,777);
node = nextnode;
mkdir("opt",node,777);
node = nextnode;
mkdir("bin",node,777);
node = nextnode;
mkdir("boot",node,777);
node = nextnode;
mkdir("selinux",node,777);
node = nextnode;
mkdir("tmp",node,777);
node = nextnode;
mkdir("var",node,777);
node = nextnode;
mkdir("lib",node,777);
node = nextnode;
mkdir("sbin",node,777);
node = nextnode;
mkdir("proc",node,777);
node = nextnode;
mkdir("root",node,700);
node = nextnode;
theLastNode = node;
node = genNode;
currentGenNode = genNode;
genUser = &cu;
}
void ls()
{
struct inode* temp;
int count = 1;
temp = currentGenNode->i_back;
while( temp != NULL )
{
count++;
if( temp->di_number == 1)
printf("%s ",temp->name);
else
count--;
if( count % 10 == 0 )
printf("\n");
temp = temp->i_back;
}
printf("\n");
}
void ll()
{
struct inode* temp;
int tt;
temp = currentGenNode->i_back;
while( temp != NULL )
{
printf("%c",temp->I_flag);
tt = temp->di_mode / 100;
if( (tt & 4) > 0 )
printf("r");
else
printf("-");
if( (tt & 2) > 0 )
printf("w");
else
printf("-");
if( (tt & 1) > 0 )
printf("x");
else
printf("-");
tt = temp->di_mode / 10 - tt*10;
if( (tt & 4) > 0 )
printf("r");
else
printf("-");
if( (tt & 2) > 0 )
printf("w");
else
printf("-");
if( (tt & 1) > 0 )
printf("x");
else
printf("-");
tt = temp->di_mode % 10;
if( (tt & 4) > 0 )
printf("r");
else
printf("-");
if( (tt & 2) > 0 )
printf("w");
else
printf("-");
if( (tt & 1) > 0 )
printf("x");
else
printf("-");
if(temp->I_flag == 'd' && temp->di_number == 1)
printf(" %6s %6s none %s/\n",PROCUSER[temp->di_uid],PROCUSER[temp->di_uid],temp->name);
else if(temp->I_flag == 'd' && temp->di_number == 0)
printf(" %6s %6s none .%s/\n",PROCUSER[temp->di_uid],PROCUSER[temp->di_uid],temp->name);
else if(temp->I_flag != 'd' && temp->di_number == 0)
printf(" %6s %6s %4d .%s\n",PROCUSER[temp->di_uid],PROCUSER[temp->di_uid],temp->f->file_size,temp->name);
else
printf(" %6s %6s %4d %s\n",PROCUSER[temp->di_uid],PROCUSER[temp->di_uid],temp->f->file_size,temp->name);
temp = temp->i_back;
}
}
void cd()
{
char dirname[20];
struct inode *temp;
struct inode *newnode;
int i;
temp = currentGenNode;
printf("Please input dirname:");
gets(dirname);
while( temp != NULL )
{
if( strcmp(temp->name,dirname) == 0 )
{
if(temp->I_flag != 'd')
{
printf("The %s isn't a dir!\n",dirname);
}
else if(CURRENTUSERUID != 0 && CURRENTUSERUID != temp->di_uid && ((temp->di_mode%10)&1) == 0)
{
printf("You don't have privilege to access the dir!\n");
}
else if(temp->downdir == NULL)
{
newnode = (struct inode *)malloc(sizeof(struct inode));
strcat(CURRENTDIR,dirname);
strcat(CURRENTDIR,"/");
newnode->i_forw = temp;
newnode->i_back = NULL;
temp->downdir = newnode;
STACKINODE[STACTINODETOP] = currentGenNode; //压栈
STACTINODETOP++; //栈顶指针++
currentGenNode = newnode; //改变当前根节点
node = newnode; //改变node值使ls,ll命令正确执行
}
else
{
strcat(CURRENTDIR,dirname);
strcat(CURRENTDIR,"/");
STACKINODE[STACTINODETOP] = currentGenNode; //压栈
STACTINODETOP++; //栈顶指针++
currentGenNode = temp->downdir;
}
break;
}
else if(strcmp("..",dirname) == 0) //上级目录,出栈
{
if(STACTINODETOP <= 0 )
{
printf("Don't have upstair dir.\n");
}
else
{
STACTINODETOP--;
currentGenNode = STACKINODE[STACTINODETOP];
for(i = strlen(CURRENTDIR)-2; i >= 0 ; i--)
if(CURRENTDIR[i] == '/')
{
CURRENTDIR[i+1] = '\0';
break;
}
}
break;
}
else
{
temp = temp->i_back;
}
}
if(temp == NULL)
printf("Don't have the dirname.\n");
}
void pwd()
{
puts(CURRENTDIR);
}
void useradd()
{
char username[20];
char pwd[20];
char ch;
struct userapass *userAndPassword;
char p[20];
struct current_u *temp;
struct current_u *newcu;
if(CURRENTUSERUID == 0)
{
temp = genUser;
printf("Input username:");
gets(username);
//printf("Input password:");
//while((ch=getch())!='\r')//判断是否是回车
/*while(1)
{
system("stty -echo");
ch = getchar();
if(ch == '\r'){
system("stty echo");
break;
}
system("stty echo");
if(ch==8)//实现backspace键的功能,其中backspace键的ascii码是8
{
if(p>0){//最多只能删到没有字符
p--;
putchar('\b');
putchar(' ');
putchar('\b');
}else{
putchar(' ');
putchar('\b');
}
continue;
}
else
putchar('*');//在屏幕上打印星号
pwd[p++]=ch;//保存密码
}
pwd[p] = '\0';*/
while(1)
{
printf("Input password 1:");
system("stty -echo");
gets(pwd);
system("stty echo");
printf("\n");
printf("Input password 2:");
system("stty -echo");
gets(p);
system("stty echo");
printf("\n");
if(strcmp(pwd,p) == 0)
break;
else
printf("Input password error,please input again!\n");
putchar('\n');
}
while(temp->np != NULL && strcmp(temp->cp->username,username) != 0)
temp = temp->np;
if( temp->np == NULL && strcmp(temp->cp->username,username) != 0)
{
newcu = (struct current_u *)malloc(sizeof(struct current_u));
userAndPassword = (struct userapass *)malloc(sizeof(struct userapass));
strcpy(PROCUSER[EFFECTCOUNT],username);
userAndPassword->uid = EFFECTCOUNT;
EFFECTCOUNT++; //有效用户数目加一
strcpy(userAndPassword->username,username);
strcpy(userAndPassword->password,pwd);
temp->np = newcu;
newcu->lp = temp;
newcu->np = NULL;
newcu->cp = userAndPassword;
printf("Create user successfully!\n");
}
else
{
printf("Username:%s isn't available!Create user failed!\n",username);
}
}
else
{
printf("You don't have privilege to create user!\n");
}
}
void cat()
{
char filename[20];
struct inode *temp;
temp = currentGenNode;
printf("Please input filename:");
gets(filename);
while(temp != NULL && strcmp(filename,temp->name) != 0 )
temp = temp->i_back;
if(temp != NULL)
{
if(temp->I_flag == 'd')
{
printf("We can't cat dir.\n");
}
else
{
if( CURRENTUSERUID != 0 && CURRENTUSERUID != temp->di_uid && ((temp->di_mode%10)&4) == 0 ){
printf("You don't have privilege to read the file!\n");
}else if(temp->f->file_size == 0)
printf("\n");
else
puts(temp->f->content);
}
}
else
{
printf("We can't find %s file.\n",filename);
}
}
void vim()
{
char filename[20];
struct inode *temp;
char content[1000];
temp = currentGenNode;
printf("Please input filename:");
gets(filename);
while(strcmp(filename,temp->name) != 0 && temp != NULL)
temp = temp->i_back;
if(temp != NULL)
{
if(temp->I_flag == 'd')
{
printf("We can't write dir.\n");
}
else
{
if( CURRENTUSERUID != 0 && CURRENTUSERUID != temp->di_uid && ((temp->di_mode%10)&2) == 0)
{
printf("You don't have the privilege to write the file!\n");
}
else
{
printf("Please input content:");
gets(content);
strcpy(temp->f->content,content);
temp->f->file_size = strlen(content) * sizeof(char);
}
}
}
else
{
printf("We can't find %s file.\n",filename);
}
}
void touch()
{
char filename[20];
struct inode *temp;
if(currentGenNode->i_back != NULL)
temp = currentGenNode->i_back;
else
temp = currentGenNode;
while(temp->i_back != NULL)
temp = temp->i_back;
nextnode = (struct inode *)malloc(sizeof(struct inode));
myfile = (struct file *)malloc(sizeof(struct file));
theLastNode = temp;
theLastNode->i_back = nextnode;
nextnode->di_uid = CURRENTUSERUID;
nextnode->di_mode = 644;
nextnode->di_number = 1;
nextnode->i_forw = theLastNode;
nextnode->i_back = NULL;
nextnode->I_flag = '-';
nextnode->f = myfile;
nextnode->downdir = NULL;
myfile->file_size = 0;
printf("Please input filename:");
gets(filename);
strcpy(nextnode->name,filename);
theLastNode = nextnode;
printf("Create file successfully!\n");
}
void eexit()
{
printf("Bye %s\n",CURRENTUSER);
}
int is_legal(int mode)
{
int hundred,ten,num;
hundred = mode / 100;
ten = mode / 10 - hundred*10;
num = mode % 10;
if(hundred>=0 && hundred <=7 && ten >= 0 && ten <= 7 && num >= 0 && num <= 7)
return 1;
else
return 0;
}
void chmod()
{
struct inode* temp;
char filename[20];
int mode;
printf("Please input filename:");
gets(filename);
temp = currentGenNode;
printf("Please input mode:");
scanf("%d%*c",&mode);
if( is_legal(mode) )
{
while(temp != NULL)
{
if(strcmp(temp->name,filename) == 0 && temp->di_number == 1 && temp->I_flag != 'd') //文件可以修改
{
if(CURRENTUSERUID != 0 && CURRENTUSERUID != temp->di_uid)
{
printf("You don't have the privilege to modify the file!\n");
break;
}
temp->di_mode = mode;
printf("Modify successfully!\n");
break;
}
else if(strcmp(temp->name,filename) == 0 && temp->di_number == 1 && temp->I_flag == 'd') //目录不允许修改
{
printf("You can't modify dir!\n");
break;
}
else
temp = temp->i_back;
}
if( temp == NULL )
printf("Don't have the file:%s\n",filename);
}
else
{
printf("Mode error!\n");
}
}
void su()
{
char username[20];
char password[20];
int p = 0;
char ch;
int count = 0;
struct current_u *log;
log = genUser;
printf("Username:");
gets(username);
while( log != NULL )
{
if( strcmp(log->cp->username,username) == 0 )
break;
else
{
log = log->np;
}
}
if( log == NULL )
{
printf("Don't have the user!\n");
}
else
{
while( count < 3) //三次机会输入密码
{
/*printf("Password:");
//while((ch = getch()) != '\r')
while(1)
{
system("stty -echo");
ch = getchar();
if(ch == '\r'){
system("stty echo");
break;
}
system("stty echo");
password[p++] = ch;
if( ch == 8 && p > 0){
p--;
}
}
password[p] = '\0';*/
printf("Input password:");
system("stty -echo");
gets(password);
system("stty echo");
if(strcmp(password,log->cp->password) == 0 )
break;
count++;
putchar('\n');
printf("You have wrong %d times,three times wrong you will switch user fail!\n",count);
p = 0;
//printf("%d\n",strlen(password));
//puts(password);
}
if( count < 3 )
{
printf("\nLog successfully!Welcome %s\n",log->cp->username);
strcpy(CURRENTUSER,log->cp->username);
CURRENTUSERUID = log->cp->uid;
}
}
}
void rm()
{
struct inode* temp;
char filename[20];
//int count = 0;
printf("Please input filename:");
gets(filename);
temp = currentGenNode;
while(temp != NULL)
{
if(strcmp(temp->name,filename) == 0 && temp->I_flag != 'd') //文件可以修改
{
if(CURRENTUSERUID != 0 && CURRENTUSERUID != temp->di_uid)
{
printf("You don't have the privilege to modify the file!\n");
break;
}
temp->i_forw->i_back = temp->i_back;
free(temp);
printf("Remove file successfully!\n");
break;
}
else if(strcmp(temp->name,filename) == 0 && temp->I_flag == 'd') //目录修改分步
{
if(CURRENTUSERUID != 0 && CURRENTUSERUID != temp->di_uid)
{
printf("You don't have the privilege to remove the file!\n");
break;
}
//else if(count == 0 && temp->downdir == NULL)
else if(temp->downdir == NULL)
{
temp->i_forw->i_back = temp->i_back;
free(temp);
printf("Remove dir successfully!\n");
break;
}
//else if( count == 0 && temp->downdir != NULL && temp->downdir->i_back == NULL && temp->downdir == NULL)
else if(temp->downdir != NULL && temp->downdir->i_back == NULL && temp->downdir->downdir == NULL)
{
free(temp->downdir);
temp->i_forw->i_back = temp->i_back;
free(temp);
printf("Remove dir successfully!\n");
break;
}
else
{
printf("You can't remove a dir with other dirs or files!\n");
break;
}
}
else
temp = temp->i_back;
//count++;
}
if( temp == NULL )
printf("Don't have the file:%s\n",filename);
}
void uv()
{
struct inode* temp;
char filename[20];
printf("Please input filename:");
gets(filename);
temp = currentGenNode->i_back;
while(temp != NULL)
{
if(strcmp(temp->name,filename) == 0 && temp->di_number == 1 && temp->I_flag != 'd') //文件可以删除
{
temp->di_number = 0;
printf("Invisiable file successfully!\n");
break;
}
else if(strcmp(temp->name,filename) == 0 && temp->di_number == 1 && temp->I_flag == 'd') //目录不允许删除
{
temp->di_number = 0;
printf("Invisiable dir successfully!\n");
break;
}
else
temp = temp->i_back;
}
if( temp == NULL )
printf("Don't have the file or dir:%s\n",filename);
}
void mmkdir()
{
struct inode *temp;
char dirname[20];
temp = currentGenNode;
printf("Please input dirname:");
gets(dirname);
while(temp->i_back != NULL && strcmp(temp->name,dirname) != 0)
temp = temp->i_back;
if(temp->i_back == NULL && strcmp(temp->name,dirname)!=0)
{
nextnode = (struct inode *)malloc(sizeof(struct inode));
nextnode->di_mode = 777;
nextnode->di_number = 1;
nextnode->di_uid = CURRENTUSERUID;
nextnode->downdir = NULL;
nextnode->f = NULL;
nextnode->i_back = NULL;
nextnode->I_flag = 'd';
nextnode->i_forw = temp;
strcpy(nextnode->name,dirname);
temp->i_back = nextnode;
printf("Make dir successfully!\n");
}
else
{
printf("The name-%s has been used.\n",dirname);
}
}
int main()
{
char command[20];
createRoot();
login();
showMenu();
initialNode();
while(1)
{
printf("%s@%s:",CURRENTUSER,CURRENTDIR);
gets(command);
if( strcmp(command,"ls") == 0 )
{
ls();
}
else if( strcmp(command,"ll") == 0 )
{
ll();
}
else if( strcmp(command,"cd") == 0 )
{
cd();
}
else if( strcmp(command,"chmod") == 0 )
{
chmod();
}
else if( strcmp(command,"pwd") == 0 )
{
pwd();
}
else if( strcmp(command,"useradd") == 0 )
{
useradd();
}
else if( strcmp(command,"cat") == 0 )
{
cat();
}
else if( strcmp(command,"vim") == 0 )
{
vim();
}
else if( strcmp(command,"exit") == 0 )
{
eexit();
break;
}
else if( strcmp(command,"touch") == 0 )
{
touch();
}
else if( strcmp(command,"su") == 0 )
{
su();
}
else if( strcmp(command,"rm") == 0 )
{
rm();
}
else if( strcmp(command,"mkdir") == 0)
{
mmkdir();
}
else if(strcmp(command,"uv") == 0)
{
uv();
}
else
{
printf("No the command\n");
}
}
return 0;
}
/*
bin dev home lib64 media opt root selinux sys usr
boot etc lib lost+found mnt proc sbin srv tmp var
*/