#ifndef __HEAD_CMD_HANDLE_H__
#define __HEAD_CMD_HANDLE_H__
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define SIZE_NAME 68
#define SIZE_ARGC 10
#define SIZE_PARAM 128
typedef struct {
char cmd_name[SIZE_NAME];
int cmd_argc;
char cmd_parse[SIZE_ARGC][SIZE_PARAM];
}command_t;
extern bool cmd_exec(char* command);
extern void cmd_intr(command_t* cmd);
extern void parse_cmd(char* command,command_t* cmd);
extern void display_cmd(command_t* );
extern int distinguish_cmd(command_t* cmd);
#endif
cmd_handle.c
#include "cmd_handle.h"
#define DENUG
#include "cmd_cp.h"
#include "cmd_ls.h"
bool cmd_exec(char* command){
if(NULL==command){
printf("empty\n");
return false;
}
command_t cmd;
cmd_intr(&cmd);
parse_cmd(command,&cmd);
#ifndef DEBUG
display_cmd(&cmd);
#endif
int num=distinguish_cmd(&cmd);
if(1==num){
printf("cmd_name:%s\n",cmd.cmd_name);
bool res=orperat_cp(&cmd);
if(res){
return true;
}else{
return false;
}
}else if(2==num){
printf("cmd_name:%s\n",cmd.cmd_name);
bool lres=orperat_ls(&cmd);
if(lres){
return true;
}else{
return false;
}
}else if(num!=1||num!=2){
printf("intput error\n");
return false;
}
}
void cmd_intr(command_t* cmd){
if(NULL==cmd){
printf("error\n");
return;
}
memset(cmd->cmd_name,0,sizeof(cmd->cmd_name));
cmd->cmd_argc=0;
for(int i=0;i<SIZE_ARGC;i++){
memset(cmd->cmd_parse[i],0,sizeof(cmd->cmd_parse[i]));
}
}
void parse_cmd(char* command,command_t* cmd){
char* cmd_name=strtok(command," ");
strcpy(cmd->cmd_name,cmd_name);
int argc=0;
char* parse=NULL;
while((parse=strtok(NULL," "))!=NULL){
strcpy(cmd->cmd_parse[argc],parse);
argc++;
}
cmd->cmd_argc=argc;
}
void display_cmd(command_t* cmd){
if(NULL==cmd){
printf("empty\n");
return;
}
printf("---------------cmd---------------\n");
printf("cmd_name:%s\n",cmd->cmd_name);
printf("cmd_argc:%d\n",cmd->cmd_argc);
for(int i=0;i<cmd->cmd_argc;i++){
printf("cmd_parse%d:%s\n",i,cmd->cmd_parse[i]);
}
printf("--------------------------------\n");
}
int distinguish_cmd(command_t* cmd){
if(strcmp(cmd->cmd_name,"cp")==0){
return 1;
}else if(strcmp(cmd->cmd_name,"ls")==0){
return 2;
}else{
return 3;
}
}
cmd_cp.h
#ifndef __HEAD_CMD_CP_H__
#define __HADE_CMD_CP_H__
#include "cmd_handle.h"
#define SIZE_SRC_FILE_NAME 128
enum FILE_TYPE{
FT_FILE=1,
FT_DIR,
FT_OTHER,
FT_ERROR=1000
};
typedef struct{
enum FILE_TYPE ft;
char src_file_name[SIZE_SRC_FILE_NAME];
}fileInfo_t;
extern void cmd_cp_parse_strpath(command_t* cmd,fileInfo_t* fileInfo);
extern bool orperat_cp(command_t*);
extern bool file_exist(char* file);
extern enum FILE_TYPE cmd_cp_prase_filetype(fileInfo_t* file);
extern int cmd_file_cp(fileInfo_t , char* dest);
extern bool cmd_cp_exec(fileInfo_t file,command_t* cmd);
extern int cmd_dir_cp(fileInfo_t file, char* dest);
#endif
cmd_cp.c
#include "cmd_cp.h"
bool orperat_cp(command_t* cmd){
if(NULL==cmd){
printf("empty\n");
return false;
}
if(cmd->cmd_argc!=2){
return false;
}
fileInfo_t fileInfo;
cmd_cp_parse_strpath(cmd,&fileInfo);
if(!(file_exist(fileInfo.src_file_name))){
printf("file is not exist\n");
}
enum FILE_TYPE ft =cmd_cp_prase_filetype(&fileInfo);
if(ft == FT_ERROR){
return false;
}
fileInfo.ft = ft;
printf("------------file--------------->\n");
printf("filetype:%d\n",fileInfo.ft);
printf("src_file_name:%s\n",fileInfo.src_file_name);
bool res= cmd_cp_exec(fileInfo,cmd);
if(!res){
return false;
}
return true;
}
bool cmd_cp_exec(fileInfo_t file,command_t* cmd){
enum FILE_TYPE ft=file.ft;
switch(ft){
case FT_FILE:
int num=cmd_file_cp(file,cmd->cmd_parse[1]);
if(-1==num){
return false;
}else{
return true;
}
break;
case FT_DIR:
printf("dest======%s\n",cmd->cmd_parse[1]);
int num2=cmd_dir_cp(file,cmd->cmd_parse[1]);
if(-1==num2){
return false;
}else{
return true;
}
break;
}
}
int cmd_dir_cp(fileInfo_t file, char* dest){
if(file.ft==FT_FILE){
return cmd_file_cp(file,dest);
}
DIR* dir=opendir(file.src_file_name);
if(NULL==dir){
perror("opendir");
return -1;
}
char* newsrc=strcat(file.src_file_name,"/");
char* newdest=strcat(dest,"/");
if(access(newdest,F_OK)==-1){
if(mkdir(newdest,0777) == -1){
perror("mkdir");
return -1;
}
}
struct dirent* dirent;
while((dirent=readdir(dir))!= NULL){
if(strcmp(dirent->d_name,".") ==0 || strcmp(dirent->d_name,"..")==0){
continue;
}
char cursrc[512]={0};
strcpy(cursrc,newsrc);
char curdest[512]={0};
strcpy(curdest,newdest);
strcat(cursrc,dirent->d_name);
strcat(curdest,dirent->d_name);
fileInfo_t fi;
strcpy(fi.src_file_name,cursrc);
fi.ft=cmd_cp_prase_filetype(&fi);
cmd_dir_cp(fi,curdest);
}
return 0;
}
int cmd_file_cp(fileInfo_t file, char* dest){
FILE* srcfile =fopen(file.src_file_name,"r");
if(srcfile==NULL){
perror("open:");
return -1;
}
FILE* destfile =fopen(dest,"w+");
if(destfile==NULL){
perror("openfile:");
return -1;
}
char buf[512]={0};
size_t rbety=0;
while(rbety=fread(buf,1,sizeof(buf),srcfile)!=0){
fwrite(buf,1,strlen(buf),destfile);
}
fclose(srcfile);
fclose(destfile);
return 1;
}
void cmd_cp_parse_strpath(command_t* cmd,fileInfo_t* fileInfo){
strcpy(fileInfo->src_file_name,cmd->cmd_parse[0]);
printf("src path:%s\n",fileInfo->src_file_name);
}
bool file_exist(char* file){
if(NULL==file){
return false;
}
return (access(file,F_OK))==0?true:false;
}
enum FILE_TYPE cmd_cp_prase_filetype(fileInfo_t* file){
struct stat statbuf;
int res = stat(file->src_file_name,&statbuf);
if(-1==res){
perror("filetype");
return FT_ERROR;
}
mode_t mode =statbuf.st_mode;
if(S_ISREG(mode)){
return FT_FILE;
}else if(S_ISDIR(mode)){
return FT_DIR;
}else{
return FT_OTHER;
}
}
cmd_ls.h
#ifndef __HADE_CMD_LS_H_
#define __HADE_CMD_LS_H_
#include "cmd_handle.h"
#define SZ_NAME 64
#define SZ_PERMISSION 10
#define SZ_TIME 64
#define SZ_LINK_CONTENT 128
// 文件属性的结构体
typedef struct {
struct stat f_attr_stat; // 系统原有的info
char f_attr_type; // 文件类型
char f_attr_uname[SZ_NAME]; // 文件的所属者
char f_attr_gname[SZ_NAME]; // 文件的所属组
char f_attr_mtime[SZ_TIME]; // 最后修改时间
char f_attr_permission[SZ_PERMISSION]; // 文件的权限
char f_attr_name[SZ_NAME]; // 文件名
char f_attr_link_content[SZ_LINK_CONTENT]; // 软链接文件名
}file_attribute_t;
extern void make_path(char* path,const char* dest);
extern bool orperat_ls(command_t* cmd);
extern bool cmd_list_directory(char* dirpath);\
extern char get_file_attr(file_attribute_t* fileAttr, char* path,const char* filename,int isSymbolicLink);
extern int getchar_file_type(file_attribute_t* fileAttr);
extern void show_file_attribute(file_attribute_t* fileAttr);
#endif
cmd_ls.c
#include "cmd_handle.h"
#include "cmd_ls.h"
bool orperat_ls(command_t* cmd){
if(NULL==cmd){
perror("orperat");
return false;
}
//if(cmd->cmd_argc==1){
//strcpy(cmd->cmd_parse[1],".");
// }else
if(cmd->cmd_argc!=1){
printf("paramemer error\n");
return false;
}
return cmd_list_directory(cmd->cmd_parse[0]);
}
bool cmd_list_directory(char* dirpath){
DIR* dir=opendir(dirpath);
if(NULL==dir){
perror("opendir");
return false;
}
file_attribute_t fileAttr;
char path[512]={0};
struct dirent* pdirent=NULL;
while((pdirent=readdir(dir))!=NULL){
if(strcmp(pdirent->d_name,".")==0 || strcmp(pdirent->d_name,"..")==0){
continue;
}
printf("filename:%s\n",pdirent->d_name);
memset(&fileAttr,0,sizeof(fileAttr));
make_path(path,dirpath);
get_file_attr(&fileAttr,path,pdirent->d_name,pdirent->d_type==DT_LNK);
}
closedir(dir);
return true;
}
void make_path(char* path,const char* dest){
strcpy(path,dest);
strcat(path,"/");
}
char get_file_attr(file_attribute_t* fileAttr, char* path,const char* filename,int isSymbolicLink){
int ret=-1;
if(isSymbolicLink){
ret=lstat(strcat(path,filename),&(fileAttr->f_attr_stat));
}else{
ret = stat(strcat(path,filename),&(fileAttr->f_attr_stat));
}
if(ret == -1)
{
perror("stat");
return -1;
}
if(getchar_file_type(fileAttr)==-1)
{
printf("get file type failed.\n");
return -1;
}
show_file_attribute(fileAttr);
return 0;
}
int getchar_file_type(file_attribute_t* fileAttr){
if(NULL == fileAttr){
return -1;
}
mode_t mode = fileAttr->f_attr_stat.st_mode;
switch(mode & S_IFMT){
case S_IFDIR:
fileAttr->f_attr_type='d';
break;
case S_IFREG:
fileAttr->f_attr_type='-';
break;
case S_IFBLK:
fileAttr->f_attr_type='b';
break;
case S_IFSOCK:
fileAttr->f_attr_type='s';
break;
case S_IFLNK:
fileAttr->f_attr_type='l';
break;
case S_IFIFO:
fileAttr->f_attr_type='p';
break;
case S_IFCHR:
fileAttr->f_attr_type='c';
break;
default:
break;
}
return 0;
}
void show_file_attribute(file_attribute_t* fileAttr){
printf("%c ",fileAttr->f_attr_type);
putchar('\n');
}
main.c
#include "cmd_handle.h"
int main()
{
char command[128]={0};
do{
printf("input order------>");
fgets(command,sizeof(command)-1,stdin);
command[strlen(command)-1]='\0';
if(strcmp(command,"exit")==0){
printf("Good Bey\n");
exit(EXIT_SUCCESS);
}else{
bool res= cmd_exec(command);
if(res){
printf("successful\n");
}else{
printf("failure\n");
}
}
}while(1);
return 0;
}