可以说这个是我写的第一个项目,也是我成长的最多的一个项目,因为这个项目我整整写了四个版本,也大概是4个程序实现的过程,一个从39行到380行的进步
/*************************************************************************
> File Name: ls1.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月21日 星期五 19时17分38秒
************************************************************************/
#include
#include
#include
//#include
void do_ls(char []);
int main(int ac,char * av[]){
if (ac == 1) {
do_ls(".");
} else {
while (--ac) {
//printf("%s:\n", *(++av));
++av;
do_ls(*av);
}
}
return 0;
}
/ls1 /
void do_ls(char dirname[]){
DIR *dir_ptr;
struct dirent *direntp;
if ((dir_ptr = opendir(dirname)) == NULL) {
fprintf(stderr, "ls1 cannot open %s\n",dirname);
} else {
while ((direntp = readdir(dir_ptr)) != NULL)
printf("%s ", direntp->d_name);
printf("\n");
closedir(dir_ptr);
}
}
这次的实现只是属于尝试版本,因为涉及到的结构体,有点陌生所以拿来练练手,但是当我看到屏幕输出的时候还是非常兴奋的
这个只是ls的基础功能,但是没有实现 -l 的功能,为此我做了第二版改进
/*************************************************************************
> File Name: ls2.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月21日 星期五 19时44分01秒
************************************************************************/
#include
#include
#include
#include
using namespace std;
void do_ls(char []);
void dotat(chat *);
void show_stat_info(char *fname, struct stat *buf);
void mode_to_letters(int mode, char str[]);
char *uid_to_name(uid_t);
char *gid_to_name(gid_t);
int main(int ac, char *av[]){
struct stat info;
if (ac > 1) {
if (stat(av[1],&info) != -1) {
show_stat_info(av[1], &info);
return 0;
}
else{
perror(av[1]);
return 1;
}
}
return 0;
}
void show_stat_info(char *fname, struct stat *buf){
printf(" mode:%o\n",buf->st_mode);
printf(" links:%d\n",buf->st_nlink);
printf(" user:%d\n",buf->st_uid);
printf(" group:%d\n",buf->st_gid);
printf(" size:%d\n",buf->st_size);
printf("modtime:%d\n",buf->st_mtime);
printf(" name:%s\n",fname);
}
void mode_to_letters(int mode, char str[]){
strcpy(str,"---------");
if (S_ISDIR(mode)) str[0] = 'd';
if (S_ISCHR(mode)) str[0] = 'c';
if (S_ISBLK(mode)) str[0] = 'b';
if (mode & S_IRUSR) str[1] = 'r';
if (mode & S_IWUSR) str[2] = 'w';
if (mode & S_IXUSR) str[3] = 'x';
if (mode & S_IRGRP) str[4] = 'r';
if (mode & S_IWGRP) str[5] = 'w';
if (mode & S_IXGRP) str[6] = 'x';
if (mode & S_IROTH) str[7] = 'r';
if (mode & S_IWOTH) str[8] = 'w';
if (mode & S_IXOTH) str[9] = 'x';
}
/*************************************************************************
> File Name: ls2.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月21日 星期五 19时44分01秒
************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
void do_ls(char []);
void dostat(char *,char *);
void show_stat_info(char *fname, struct stat *buf);
void mode_to_letters(int mode, char str[]);
char *uid_to_name(uid_t);
char *gid_to_name(gid_t);
int main(int ac, char *av[]){
if (ac == 1) {
do_ls(".");
} else {
while(--ac){
//printf("%s:\n", *(++av));
av++;
do_ls( *av );
}
}
return 0;
}
void do_ls(char dirname[]){
DIR *dir_ptr;
struct dirent * direntp;
if ((dir_ptr = opendir(dirname)) == NULL){
fprintf(stderr, "ls22:connot open %s\n", dirname);
} else {
while (( direntp = readdir(dir_ptr)) != NULL){
dostat(direntp->d_name,dirname);
}
closedir(dir_ptr);
}
}
void dostat( char *filename ,char dirname[]){
struct stat info;
char pwdname[1000];
//memset(pwdname,0,sizeof(pwdname));
strcpy(pwdname,dirname);
if(strcmp(dirname,".") == 0){
strcpy(pwdname,filename);
} else if (strcmp(dirname,"/") == 0){
strcat(pwdname,filename);
} else {
strcat(strcat(pwdname,"/"), filename);
}
//printf("dirname:%s\n filename:%s\n",dirname,filename);
if(stat(pwdname, &info) == -1){
perror(filename);
} else {
show_stat_info(filename, &info);
}
}
void show_stat_info(char *filename, struct stat *info_p){
//char *uid_to_name(), *gid_to_name(), *filemode();
//void mode_to_letters();
char modestr[11];
mode_to_letters(info_p->st_mode, modestr);
printf("%s", modestr);
printf("%4d ", (int)info_p->st_nlink);
printf("%-8s ", uid_to_name(info_p->st_uid));
printf("%-8s ", gid_to_name(info_p->st_gid));
printf("%8ld ", (long) info_p->st_size);
printf("%.12s ", 4 + ctime(&info_p->st_mtime));
printf("%-4d", info_p->st_blocks/2);
printf("%s\n", filename);
}
void mode_to_letters(int mode, char str[]){
strcpy(str,"----------");
if (S_ISDIR(mode)) str[0] = 'd';
if (S_ISCHR(mode)) str[0] = 'c';
if (S_ISBLK(mode)) str[0] = 'b';
if (mode & S_IRUSR) str[1] = 'r';
if (mode & S_IWUSR) str[2] = 'w';
if (mode & S_IXUSR) str[3] = 'x';
if (mode & S_IRGRP) str[4] = 'r';
if (mode & S_IWGRP) str[5] = 'w';
if (mode & S_IXGRP) str[6] = 'x';
if (mode & S_IROTH) str[7] = 'r';
if (mode & S_IWOTH) str[8] = 'w';
if (mode & S_IXOTH) str[9] = 'x';
}
char* uid_to_name(uid_t uid){
//struct passwd * getpwuid(), *pw_ptr;
struct passwd *pw_ptr;
static char numstr[10];
if ((pw_ptr = getpwuid(uid)) == NULL){
sprintf(numstr,"%d", uid);
return numstr;
}else{
return pw_ptr->pw_name;
}
}
char* gid_to_name(gid_t gid){
//struct group *getgrgid(), *grp_ptr;
struct group *grp_ptr;
static char numstr[10];
if((grp_ptr = getgrgid(gid)) == NULL){
sprintf(numstr,"%d", gid);
return numstr;
}else{
return grp_ptr->gr_name;
}
}
可以看到这一版和上一版,你不会想到是一个人在隔了一天写出的代码,可以看出来进步是多么明显
这个与上个实现的功能的不同,只能实现-l的功能,不能传递参数,而且没有颜色的功能,一般的ls都是有功能的,所以我做出了第三版本
/*************************************************************************
> File Name: ls2.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月21日 星期五 19时44分01秒
************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define BROWN "\e[0;33m"
#define NONE "\e[0m"
#define BLUE "\e[0;34m"
void do_ls(char [], int);
void print(char *ch);
void dostat(char *,char *,int);
void show_stat_info(char *fname, struct stat *buf,int gon);
void mode_to_letters(int mode, char str[]);
char *uid_to_name(uid_t);
char *gid_to_name(gid_t);
int main(int ac,char *av[]){
int temp = 0,i = 2; //00 低位是a,高位是l
*(++av);
for(i = 2; i <= ac && (*av)[0] == '-'; *(++av),i++){
strlen(*av) == 2 && (*av)[1] =='a'&& (temp |=1,1)||(*av)[1] == 'l' && (temp |= 2,1);
strlen(*av) == 3 && ((*av)[1] == 'a' && (*av)[2] == 'l' ||
(*av)[1] == 'l' && (*av)[2] == 'a') && (temp |= 3,1);
}
if (i > ac) {
do_ls(".",temp);
}else if (i == ac) {
do_ls(*av,temp);
}
else{
while(i <= ac){
printf("%s:\n",*av);
do_ls(*av,temp);
*(++av);
i++;
}
}
return 0;
}
int comp(const void *a, const void *b){
return strcmp((char *)a, (char *)b);
}
void do_ls(char *dirname, int gon){
DIR *dir_ptr;
struct dirent *direntp;
struct stat dir;
char name[1000][255];
int tn = 0;
if ((dir_ptr = opendir(dirname)) == NULL) {
fprintf(stderr, "ls3:connot open %s\n", dirname);
} else {
while((direntp = readdir(dir_ptr)) != NULL){
if(gon & 1){
//1
strcpy(name[tn],direntp->d_name);
tn++;
}else{
if(direntp->d_name[0] == '.') continue;
strcpy(name[tn],direntp->d_name);
tn++;
}
}
}
qsort(name,tn,sizeof(name[0]),comp);
for(int i = 0; i < tn; i++){
dostat(name[i],dirname,gon);
}
printf("\n");
}
void dostat( char *filename ,char dirname[],int gon){
struct stat info;
char pwdname[1000];
strcpy(pwdname,dirname);
if(strcmp(dirname,".") == 0){
strcpy(pwdname,filename);
} else if (strcmp(dirname,"/") == 0){
strcat(pwdname,filename);
} else {
strcat(strcat(pwdname,"/"), filename);
}
if(stat(pwdname, &info) == -1){
perror(filename);
} else {
show_stat_info(filename, &info,gon);
}
}
void show_stat_info(char *filename, struct stat *info_p,int gon){
char modestr[11];
mode_to_letters(info_p->st_mode, modestr);
if(gon & 2){
printf("%s", modestr);
printf("%4d ", (int)info_p->st_nlink);
printf("%-8s ", uid_to_name(info_p->st_uid));
printf("%-8s ", gid_to_name(info_p->st_gid));
printf("%8ld ", (long) info_p->st_size);
printf("%.12s ", 4 + ctime(&info_p->st_mtime));
if (modestr[0] == 'd') printf(BROWN "%s\n" NONE, filename);
else if(modestr[0] == '-') printf(BLUE "%s\n" NONE, filename);
}else{
if (modestr[0] == 'd') printf(BROWN "%s " NONE, filename);
else if(modestr[0] == '-') printf(BLUE "%s " NONE, filename);
}
}
void mode_to_letters(int mode, char str[]){
strcpy(str,"----------");
if (S_ISDIR(mode)) str[0] = 'd';
if (S_ISCHR(mode)) str[0] = 'c';
if (S_ISBLK(mode)) str[0] = 'b';
if (mode & S_IRUSR) str[1] = 'r';
if (mode & S_IWUSR) str[2] = 'w';
if (mode & S_IXUSR) str[3] = 'x';
if (mode & S_IRGRP) str[4] = 'r';
if (mode & S_IWGRP) str[5] = 'w';
if (mode & S_IXGRP) str[6] = 'x';
if (mode & S_IROTH) str[7] = 'r';
if (mode & S_IWOTH) str[8] = 'w';
if (mode & S_IXOTH) str[9] = 'x';
}
char* uid_to_name(uid_t uid){
struct passwd *pw_ptr;
static char numstr[10];
if ((pw_ptr = getpwuid(uid)) == NULL){
sprintf(numstr,"%d", uid);
return numstr;
}else{
return pw_ptr->pw_name;
}
}
char* gid_to_name(gid_t gid){
struct group *grp_ptr;
static char numstr[10];
if((grp_ptr = getgrgid(gid)) == NULL){
sprintf(numstr,"%d", gid);
return numstr;
}else{
return grp_ptr->gr_name;
}
}
这次可以说是比较完美的了,而且他还可以解析多个文件加,文件名也对齐了
完美总是想着跟完美,所以我就进行了我当时能做的最后一步
/*************************************************************************
> File Name: ls4_1.cpp
> Author: ldc
> Mail: litesla
> Created Time: 2018年09月22日 星期六 19时07分39秒
************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
//Macro definition
#define NONE "\e[0m"
#define BLACK "\e[0;30m"
#define L_BLACK "\e[1;30m"
#define RED "\e[0;31m"
#define L_RED "\e[1;31m"
#define GREEN "\e[0;32m"
#define L_GREEN "\e[1;32m"
#define BROWN "\e[0;33m"
#define YELLOW "\e[1;33m"
#define BLUE "\e[0;34m"
#define L_BLUE "\e[1;34m"
#define PURPLE "\e[0;35m"
#define L_PURPLE "\e[1;35m"
#define CYAN "\e[0;36m"
#define L_CYAN "\e[1;36m"
#define GRAY "\e[0;37m"
#define WHITE "\e[1;37m"
#define BOLD "\e[1m"
#define UNDERLINE "\e[4m"
#define BLINK "\e[5m"
#define REVERSE "\e[7m"
#define HIDE "\e[8m"
#define CLEAR "\e[2J"
#define CLRLINE "\r\e[K" //or "\e[1K\r"
#define maxn 1000
#define chlen 255
#define qu 11
//end///
//Structure declaration
typedef struct Node{
char name[chlen];
//char pwdname[maxn];
char jur[qu];
int nlink;
long size;
char ctim[chlen];
struct stat filestat;
char uidname[chlen];
char gidname[chlen];
}Node;
typedef struct forlen0{
int uid;
int gid;
int links;
}forlen0;
//end///
//Function declaration
//Function0
//main
//参数处理
//Function1
//init
//全局变量初始化
void init();
//Function2
//do_ls
//得到每个文件的名字 和当前目录文件总数 完成后续操作
void do_ls(char *);
//Function3
//dostat
//得到每个文件的具体信息
void dostat(char *, int);
//Function4
//show_stat_info
//将信息输入进去 和字符转化 统计对齐格式
void show_stat_info(int,struct stat*);
//Function5
//mod_to_letters
//将权限转化为字符串
void mod_to_letters(int, char *);
//Function6
//uid_to_name
//将uid转化成对应的名字 获取对齐长度
void uid_to_name(int,uid_t);
//Function7
//gid_to_name
//将gid转化成对应的名字 获取对齐长度
void gid_to_name(int,gid_t);
//Function8
//print1
//普通输出
void print1(int);
//Function9
//print2
//长格式输出
void print2(int);
//end///
//Global variable declaration
Node files[maxn];
forlen0 forlen;
int op = 0;//00 la
int total;
//end///
//
//正文
int main(int ac,char *av[]){
init();
int opp = 0, i = 2; //00 la
*(++av);
for(i = 2; i <= ac && (*av)[0] == '-'; *(++av),i++){
strlen(*av) == 2 && (*av)[1] =='a'&& (opp |=1,1)||(*av)[1] == 'l' && (opp |= 2,1);
strlen(*av) == 3 && ((*av)[1] == 'a' && (*av)[2] == 'l' ||
(*av)[1] == 'l' && (*av)[2] == 'a') && (opp |= 3,1);
}
op = opp;
if (i > ac) {
//默认文件夹
do_ls(".");
} else if (i == ac) {
//指定一个文件夹
do_ls(*av);
}
else {
while(i <= ac){
//指定多个文件夹
printf("%s:\n", *av);
do_ls(*av);
*(++av);
i++;
printf("\n");
init();
}
}
return 0;
}
void init(){
memset(files,0,sizeof(Node)*maxn);
forlen.uid = 0;
forlen.gid = 0;
forlen.links = 0;
total = 0;
}
//Function2
//get_filename
//得到每个文件的名字 和当前目录文件总数 完成后续操作
int comp(const void *a, const void *b){
return strcmp((*(Node*)a).name, (*(Node*)b).name);
}
void do_ls(char *dirname){
DIR *dir_ptr;
struct dirent *direntp;
struct stat dir;
int tn = 0;
if ((dir_ptr = opendir(dirname)) == NULL) {
fprintf(stderr, "ls5:connot open %s\n", dirname);
} else {
while((direntp = readdir(dir_ptr)) != NULL){
if(op & 1){
//1
strcpy(files[tn].name,direntp->d_name);
tn++;
}else{
if(direntp->d_name[0] == '.') continue;
strcpy(files[tn].name,direntp->d_name);
tn++;
}
}
}
qsort(files,tn,sizeof(files[0]),comp);
for(int i = 0; i < tn; i++) dostat(dirname, i);
if(op & 2) print2(tn);
else print1(tn);
}
//Function3
//dostat
//得到每个文件的具体信息
void dostat(char *dirname,int i){
struct stat info;
char pwdname[1000];
strcpy(pwdname,dirname);
if(strcmp(dirname,".") == 0){
strcpy(pwdname,files[i].name);
} else if (strcmp(dirname,"/") == 0){
strcat(pwdname,files[i].name);
} else {
strcat(strcat(pwdname,"/"), files[i].name);
}
//strcpy(files[i].pwdname,pwdname);
if(stat(pwdname, &info) == -1){
perror(files[i].name);
} else {
show_stat_info(i,&info);
}
}
//Function4
//show_stat_info
//将信息输入进去 和字符转化 统计对齐格式
void show_stat_info(int i,struct stat* info_p){
forlen.links = forlen.links < log10((int)info_p->st_nlink) ? log10((int)info_p->st_nlink) : forlen.links;
files[i].nlink = (int)info_p->st_nlink;
files[i].size = (long)info_p->st_size;
strcpy(files[i].ctim, 4 + ctime(&info_p->st_mtime));
mod_to_letters(info_p->st_mode, files[i].jur);
uid_to_name(i,info_p->st_uid);
gid_to_name(i,info_p->st_gid);
total += info_p->st_blocks/2;
}
//Function5
//mod_to_letters:
//将权限转化为字符串
void mod_to_letters(int mode, char *str){
strcpy(str,"----------");
if (S_ISDIR(mode)) str[0] = 'd';
if (S_ISCHR(mode)) str[0] = 'c';
if (S_ISBLK(mode)) str[0] = 'b';
if (mode & S_IRUSR) str[1] = 'r';
if (mode & S_IWUSR) str[2] = 'w';
if (mode & S_IXUSR) str[3] = 'x';
if (mode & S_IRGRP) str[4] = 'r';
if (mode & S_IWGRP) str[5] = 'w';
if (mode & S_IXGRP) str[6] = 'x';
if (mode & S_IROTH) str[7] = 'r';
if (mode & S_IWOTH) str[8] = 'w';
if (mode & S_IXOTH) str[9] = 'x';
}
//Function6
//uid_to_name
//将uid转化成对应的名字 获取对齐长度
void uid_to_name(int i,uid_t uid){
struct passwd *pw_ptr;
static char numstr[10];
if((pw_ptr = getpwuid(uid)) == NULL){
sprintf(numstr,"%d", uid);
strcpy(files[i].uidname, numstr);
forlen.uid = forlen.uid < strlen(numstr) ? strlen(numstr):forlen.uid;
}else{
strcpy(files[i].uidname, pw_ptr->pw_name);
forlen.uid = forlen.uid < strlen(pw_ptr->pw_name) ? strlen(pw_ptr->pw_name):forlen.uid;
}
return ;
}
//Function7
//gid_to_name
//将gid转化成对应的名字 获取对齐长度
void gid_to_name(int i, gid_t gid){
struct group *grp_ptr;
static char numstr[10];
if((grp_ptr = getgrgid(gid)) == NULL){
sprintf(numstr,"%d", gid);
strcpy(files[i].gidname, numstr);
forlen.gid = forlen.gid < strlen(numstr) ? strlen(numstr):forlen.gid;
}else{
strcpy(files[i].gidname, grp_ptr->gr_name);
forlen.gid = forlen.gid < strlen(grp_ptr->gr_name) ? strlen(grp_ptr->gr_name):forlen.gid;
}
return ;
}
//Function8
//print1
//普通输出
void print1(int tn){
for(int i = 0; i< tn; i++){
if (files[i].jur[0] == 'd')
printf(YELLOW "%s " NONE, files[i].name);
else if (files[i].jur[0] == 'c')
printf(RED "%s " NONE, files[i].name);
else if (files[i].jur[0] == 'b')
printf(CYAN "%s " NONE, files[i].name);
else if (files[i].jur[3] == 'x'||files[i].jur[6] == 'x'|| files[i].jur[9])
printf(L_BLUE "%s " NONE,files[i].name);
else if (files[i].jur[0] == '-')
printf(BLUE "%s " NONE, files[i].name);
}
printf("\n");
}
//Function9
//print2
//长格式输出
void print2(int tn){
printf("total: %d\n",total);
for(int i = 0; i< tn; i++){
printf("%s ", files[i].jur);
printf("%-*d ", forlen.links+1,files[i].nlink);
printf("%-*s ", forlen.uid+1, files[i].uidname);
printf("%-*s ", forlen.gid+1, files[i].gidname);
printf("%8ld ", files[i].size);
printf("%.12s ", files[i].ctim);
if (files[i].jur[0] == 'd')
printf(YELLOW "%s\n" NONE, files[i].name);
else if (files[i].jur[0] == 'c')
printf(RED "%s\n" NONE, files[i].name);
else if (files[i].jur[0] == 'b')
printf(CYAN "%s\n" NONE, files[i].name);
else if (files[i].jur[3] == 'x'||files[i].jur[6] == 'x'|| files[i].jur[9])
printf(L_BLUE "%s\n" NONE,files[i].name);
else if (files[i].jur[0] == '-')
printf(BLUE "%s\n" NONE, files[i].name);
}
}
//end/
虽然显示与上次没有什么差别,但是思想却差别巨大,已经有了封装的雏形
其实这次的代码还是有不完美的地方,比如函数接口处理部分,比如ls软连接部等
int opp = 0, i = 2; //00 la
*(++av);
for(i = 2; i <= ac && (*av)[0] == '-'; *(++av),i++){
strlen(*av) == 2 && (*av)[1] =='a'&& (opp |=1,1)||(*av)[1] == 'l' && (opp |= 2,1);
strlen(*av) == 3 && ((*av)[1] == 'a' && (*av)[2] == 'l' ||
(*av)[1] == 'l' && (*av)[2] == 'a') && (opp |= 3,1);
}
op = opp;