⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 command.cpp

📁 对linuix 文件系统的模拟,包含了若干文件命令
💻 CPP
字号:
#include "command.h"
#include <windows.h>
#include "global.h"
#include "dir.h"
#include <sstream>
#include <string>
#include <fstream>


namespace gilyou
{

void do_cd(char args[])//ok
{
    if(args[0] == '.' && args[1] == '\0')
        print(current_dir.d_name,INDENT | NEW_LINE);
    else if(args[0] == '\0')
        copy_dir(current_dir,root_dir);
    else
        cd(args);
}

void cd(char path[])//ok
{
    dir_t dir;
    copy_dir(dir,current_dir);
    if(read_dir(path,dir) == ALREADY_EXISTS)/********************* bug **********************/
        copy_dir(current_dir,dir);
}

void do_mkdir(char args[])//ok
{
    //print("action mkdir",INDENT | NEW_LINE);
    if(args[0] == '\0')
        print("directory needed.",INDENT | NEW_LINE);
    else{
        char path[BUFF_SIZE],d_name[BUFF_SIZE];
        int index = replace_last(args,' ','/');
        std::istringstream iss(args);
        if(index == 0){
            path[0] = '/';
            path[1] = '\0';
            iss>>d_name;
        }
        else if(index == -1){
            path[0] = '\0';
            iss>>d_name;
        }
        else{
            iss>>path>>d_name;
        }
        mkdir(path,d_name);
    }
}

void mkdir(char path[],char d_name[],bool change_dir)//ok
{
    dir_t dir;
    init_dir(dir);
    uchar result = ALREADY_EXISTS;
    bool start_current = false;
    if(path[0] == '\0'){
        copy_dir(dir,current_dir);
        start_current = true;
    }
    else
        result = read_dir(path,dir);
    if(result != ALREADY_EXISTS){
        print("some parent directory not exists",INDENT | NEW_LINE);
        return;
    }
    int index = -1;
    for(uint i=0;i<I_DIR_SIZE;i++){
        if(string_equal(d_name,dir.idir[i].name)){
            print(string_cat(3,"file $",d_name,"$ already exist."),INDENT | NEW_LINE);
            return;
        }
        else if(dir.idir[i].name[0] == '\0' && index == -1)
            index = i;
    }
    if(index == -1){
        print(string_cat(3,"can not create any more directory or files in directory $",path,"$"),INDENT | NEW_LINE);
        return;
    }
    dir_t cdir;
    init_dir(cdir);
    cdir.i_number = get_inode();
    set_inode(cdir.i_number);
    dir.idir[index].i_number = cdir.i_number;//子节点
    strcpy(dir.idir[index].name,d_name);
    dir.idir[index].type = DIRECT_FILE;
    cdir.idir[0].i_number = cdir.i_number;//本节点
    cdir.idir[1].i_number = dir.i_number;// 父节点
    strcpy(cdir.creator,current_usr.uname);
    strcpy(cdir.d_name,d_name);
    cdir.size = 0;
    time_t timer = time(NULL);
    cdir.atime = timer;
    cdir.mtime = timer;
    cdir.ctime = timer;
    cdir.mask = 0;
    cdir.mask = (current_usr.gid << (GID_BITS + UID_BITS + SELF_BITS + GROUP_BITS + OTHER_BITS) | current_usr.uid << ( UID_BITS + SELF_BITS + GROUP_BITS + OTHER_BITS) | 000000000640);
    di_write(cdir);
    di_write(dir);
    if(start_current)
        copy_dir(current_dir,dir);
    if(change_dir)
        copy_dir(current_dir,cdir);
}

void do_rmdir(char args[])
{
    //print("action rmdir",INDENT | NEW_LINE);
    rmdir(args);
}

void rmdir(char file_name[])
{
    dir_t dir;
    init_dir(dir);
    if(file_name[0] == '\0'){
        print("destination file name needed.",INDENT | NEW_LINE);
        return;
    }
    char t_file_name[BUFF_SIZE];
    strcpy(t_file_name,file_name);
    if(read_dir(t_file_name,dir) == NOT_EXISTS)
        return;//print(string_cat(3,"directory $",file_name,"$ does not exists."),INDENT | NEW_LINE);
    else{
        dir_t pdir;
        init_dir(pdir);
        char dname[BUFF_SIZE];
        int result = replace_last(file_name,' ','/');
        if(result == -1 || result == 0)
            strcpy(dname,file_name);
        else{
            char t_string[BUFF_SIZE];
            std::istringstream iss(file_name);
            iss>>t_string>>dname;
        }
        di_read(dir.idir[1].i_number,pdir);
        for(uint i=0;i<I_DIR_SIZE;i++){
            if(string_equal(dname,pdir.idir[i].name)){
                pdir.idir[i].name[0] = '\0';
                uint size;
                recycle(dir,size);

                #if DEBUG
                print("size = ",INDENT)
                print(size,NEW_LINE);
                #endif

                //set_inode(pdir.idir[i].i_number,NOT_USED);
                di_write(pdir);
                if(string_equal(current_dir.d_name,pdir.d_name))
                    copy_dir(current_dir,pdir);
                break;
            }
        }
    }
}

void do_mv(char args[])
{
    //print("action mv",INDENT | NEW_LINE);
    std::stringstream iss(args);
    char dest[BUFF_SIZE],src[BUFF_SIZE];
    iss>>src>>dest;
    mv(src,dest);
}

void mv(char src_path[],char dest_path[])
{
    dir_t src_dir,dst_dir;
    init_dir(src_dir);
    init_dir(dst_dir);
    read_dir(src_path,src_dir);
    read_dir(dest_path,dst_dir);
    for(uint i=0;i<I_DIR_SIZE;i++){
        if(dst_dir.idir[i].name[0] == '\0'){
            dst_dir.idir[i].type = DIRECT_FILE;
            strcpy(dst_dir.idir[i].name,src_dir.d_name);
            dst_dir.idir[i].i_number = src_dir.i_number;
            break;
        }
    }
    dir_t pdir;
    init_dir(pdir);
    uint inode = src_dir.idir[1].i_number;
    di_read(inode,pdir);
    for(uint i=0;i<I_DIR_SIZE;i++){
        if(string_equal(src_dir.d_name,pdir.idir[i].name)){
            pdir.idir[i].name[0] = '\0';
            break;
        }
    }
    di_write(pdir);
}

void do_cp(char args[])
{
    //print("action cp",INDENT | NEW_LINE);
    std::stringstream iss(args);
    char src_file[BUFF_SIZE];
    char dst_file[BUFF_SIZE];
    iss>>dst_file>>src_file;
    cp(dst_file,src_file);
}

void cp(char file_dest[],char file_src[])
{
    uint i_number = get_inode();
    dir_t src_dir,dst_dir;
    init_dir(src_dir);
    init_dir(dst_dir);
    if(read_dir(file_src,src_dir) == NOT_EXISTS){
        print(string_cat(3,"directory $",file_src,"$ not exists."),INDENT | NEW_LINE);
        return;
    }
    if(read_dir(file_dest,dst_dir) == NOT_EXISTS){
        print(string_cat(3,"directory $",file_src,"$ not exists."),INDENT | NEW_LINE);
        return;
    }
    copy_dir(dst_dir,src_dir);
    dst_dir.i_number = i_number;
    di_write(dst_dir);
    set_inode(i_number);
}

void do_ls(char args[])
{
    //print("action ls",INDENT | NEW_LINE);
    ls(args);
}

void ls(char file_name[])
{
    dir_t dir;
    init_dir(dir);
    if(file_name[0] == '\0')
        copy_dir(dir,current_dir);
    else
        read_dir(file_name,dir);
    int total = 0;
    char auth[10];
    dir_t cdir;
    init_dir(cdir);
    for(uint i=0;i<I_DIR_SIZE;i++){
        if(dir.idir[i].name[0] != '\0' && !string_equal(dir.idir[i].name,".") && !string_equal(dir.idir[i].name,"..")){
            di_read(dir.idir[i].i_number,cdir);
            total ++;
            print(total,INDENT);
            if(cdir.idir[i].type == DIRECT_FILE)
                print("     d",GENERIC);
            else
                print("     _",GENERIC);
            auth_to_arry(cdir.mask,auth);
            print(string_cat(4,auth,"      ",dir.idir[i].name,"      "),GENERIC);
            print(ctime(&(cdir.ctime)),GENERIC);
        }
    }
    print("total :",INDENT);
    print(total,NEW_LINE);
    //print()
}

void do_chmod(char args[])
{
    //print("action chmod",INDENT | NEW_LINE);
    std::istringstream iss(args);
    char filename[BUFF_SIZE];
    uint auth = 0;
    iss>>filename>>auth;
    if(auth > 1024){
        print("masks should not bigger than 1023",INDENT | NEW_LINE);
        return;
    }
    chmod(filename,auth);
}

void chmod(char file_name[],uint auth)
{
    to_oct(auth);
    dir_t dir;
    init_dir(dir);
    read_dir(file_name,dir);
    dir.mask = dir.mask & 0xFFFFF100;
    dir.mask = dir.mask | auth;
    di_write(dir);
}

void do_delusr(char args[])
{
    //print("action delusr",INDENT | NEW_LINE);
    if(! usr_exists(args)){
        print(string_cat(3,"user $",args,"$ not exists"),INDENT | NEW_LINE);
        return;
    }
    delusr(args);
}

void delusr(char name[])
{
    std::fstream fs;
    fs.open("sys\\usr.info",std::ios::in | std::ios::out);
    if(fs.fail()){
        print("read file sys\\usr.info fail.",INDENT | NEW_LINE);
        return;
    }
    char buffs[COMMAND_SIZE];
    std::istringstream iss;
    user_t usr;
    std::ios::pos_type start = 0;
    while(!fs.eof()){
        start = fs.tellg();
        fs.getline(buffs,COMMAND_SIZE);
        replace(buffs,' ',':');
        iss.clear();
        iss.str(buffs);
        iss>>usr.uname>>usr.upasswd>>usr.deleted>>usr.uid>>usr.gid>>usr.home>>usr.ihome>>usr.ctime>>usr.atime;
        if(string_equal(usr.uname,name) && (usr.deleted == NOT_DELETED)){
            fs.seekp(start);
            fs.clear();
            fs<<usr.uname<<":"<<usr.upasswd<<":1:"<<usr.uid<<":"<<usr.gid<<":"<<usr.home<<":"<<usr.ihome<<":"<<usr.ctime<<":"<<usr.atime;
            fs.flush();
            fs.close();
            char home_dir[BUFF_SIZE*2];
            memset(home_dir,'\0',BUFF_SIZE);
            strcat(home_dir,"/home/");
            strcat(home_dir,usr.uname);
            rmdir(home_dir);
            return;
        }
    }
}

void do_addusr(char args[])
{
    char name[BUFF_SIZE];
    char passwd[BUFF_SIZE];
    uint uid;
    uint gid;
    std::istringstream iss(args);
    iss>>name>>passwd>>uid>>gid;
    addusr(name,passwd,uid,gid);
}

void addusr(char name[],char passwd[],uint uid,uint gid)
{
    if(! usr_exists(name)){
        std::fstream fs("sys\\usr.info",std::ios::out | std::ios::app);
        if(fs.fail()){
            print("file sys\\usr.info missed.",INDENT | NEW_LINE);
            return;
        }
        time_t timer = time(NULL);
        dir_t dir;
        init_dir(dir);
        copy_dir(dir,current_dir);
        char home[6] = "/home";
        mkdir(home,name,true);
        uint ihome = current_dir.i_number;
        copy_dir(current_dir,dir);
        fs<<"\n"<<name<<":"<<passwd<<":0:"<<uid<<":"<<gid<<":"<<name<<":"<<ihome<<":"<<timer<<":"<<timer;
        fs.flush();
        fs.close();
    }
    else
        print(string_cat(3,"user $",name,"$ already exists."),INDENT | NEW_LINE);
}

void do_full_screen()//ok
{
    full_screen();
}

void history()//ok
{
    for(uint i=0;i<(BUFF_SIZE/2);i++)
        if(hists[i][0] != '\0'){
            print((i));
            print(string_cat(2," :",hists[i]), NEW_LINE);
        }
}

void  clear()//ok
{
    system("cls");
}

void  version()//ok
{
    system("title Gilyou Studio(C)");
    print("Linux File System Demo ",INDENT | NEW_LINE);
    print("xiaox(TM) gilyou(C) ",INDENT | NEW_LINE);
    print("version 0.0",INDENT | NEW_LINE);
    print("[Gilyou ^_^ Studio] works\n",INDENT | NEW_LINE);
}

void sync()//ok
{
    print("writing back...",INDENT);
    system("bin\\delay.exe 1000");
    print("\n",GENERIC);
}

void auth_to_arry(uint mask,char auth[])//长度须大于10
{
    auth[9] = '\0';
    for(int i=0;i<9;i++){
        if(i % 3 == 0)
            auth[i] = ((mask >> (8-i)) & 0x00000001) == 0?'_':'r';
        else if(i % 3 == 1)
            auth[i] = ((mask >> (8-i)) & 0x00000001) == 0?'_':'w';
        else
            auth[i] = ((mask >> (8-i)) & 0x00000001) == 0?'_':'x';
    }
}

uint to_oct(uint &mask)
{
    int third = mask % 10;
    int second = (mask / 10) % 10;
    int first = mask / 100;
    mask = 0;
    mask = (mask | first) << 3;
	mask = (mask | second) << 3;
	mask = (mask | third);
    return mask;
}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -