嵌入式学习29(自实现ls -l)

我们已经会遍历文件夹,并会用stat获得文件夹中个文件的信息了,那么如何将其转化为,ll命令下我们能很方便识别的内容呢。
首先要了解stat的的成员st_mode,它是一个6位八进制数,也就是一个18位的二进制数。
(相应位置1代表有相应权限)
000000 000 000 000 000
文件类型 文件访问权限控制 所属者 同组 其他人(权限)

S_IFMT          0170000     文件类型的位遮罩
S_IFSOCK        0140000     socket"s")
S_IFLNK         0120000     符号链接(symbolic link)                   ("l")
S_IFREG         0100000     一般文件                                  ("-")
S_IFBLK         0060000     区块装置(block device)                    ("b")           
S_IFDIR         0040000     目录                                      ("d")
S_IFCHR         0020000     字符装置(character device)                ("c")
S_IFIFO         0010000     先进先出(fifo)                            ("p")
S_ISUID         0004000     文件的(set user-id on execution)位
S_ISGID         0002000     文件的(set group-id on execution)位
S_ISVTX         0001000     文件的sticky位
S_IRWXU         00700       文件所有者的遮罩值(即所有权限值)
S_IRUSR         00400       文件所有者具可读取权限
S_IWUSR         00200       文件所有者具可写入权限
S_IXUSR         00100       文件所有者具可执行权限
S_IRWXG         00070       用户组的遮罩值(即所有权限值)
S_IRGRP         00040       用户组具可读取权限
S_IWGRP         00020       用户组具可写入权限
S_IXGRP         00010       用户组具可执行权限
S_IRWXO         00007       其他用户的遮罩值(即所有权限值)
S_IROTH         00004       其他用户具可读取权限
S_IWOTH         00002       其他用户具可写入权限
S_IXOTH         00001       其他用户具可执行权限
摘自《Linux C 函数库参考手册》```

判断时,既可以相与判断,也可以用系统的宏快速判断。


另一个知识点是/etc/passwd ,该文件是系统的主要文件之一。该文件中包含了所有用户登录名清单;为所有用户指定了主目录;在登录时使用的 shell 程序名称等。该文件还保存了用户口令;给每个用户提供系统识别号。
/etc/passwd 文件是一个纯文本文件,每行采用了相同的格式:name:password:uid:gid:comment:home:shell

struct passwd {
char pw_name; / username */
char pw_passwd; / user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char pw_gecos; / user information */
char pw_dir; / home directory */
char pw_shell; / shell program */
};




好了铺垫了这么久,我们来上最后的代码


哎,头文件不知道怎么了,无法正常显示,大佬们自行添加

char* check_rights(mode_t s);
char file_type(mode_t s);

void main(int argc,char** argv)
{
if(strcmp(argv[1],”-l”)!=0)
{
printf(“参数有误\n”);
return;
}
DIR* dirp=opendir(“./”);//文件夹指针
if(NULL==dirp)
{
perror(“dirp”);
return;
}
struct dirent* the=NULL;//文件指针,含文件的上下文件,文件名等信息
struct stat sta;
struct passwd* pw;//用户信息指针
struct group* gr;
char buf[10];
struct tm* t;//实例化tm结构指针
while(the=readdir(dirp))//每读取成功一次,读写指针自动下移遍历
{
if(strcmp(the->d_name,”.”)!=0 && strcmp(the->d_name,”..”)!=0 && ((char)the->d_name)!=’.’)
{
stat(the->d_name,&sta);//获取文件信息,存入sta结构体

/* printf(“%d “,sta.st_dev);//文件所在设备ID
printf(“%d “,sta.st_ino);//节点号
printf(“%d “,sta.st_mode);//保护模式
printf(“%d “,sta.st_nlink);//连接数
printf(“%d “,sta.st_uid);//
printf(“%d “,sta.st_gid);//
printf(“%d “,sta.st_rdev);//设备号
printf(“%d “,sta.st_size);//文件大小
printf(“%d “,sta.st_blksize);//系统块的大小
printf(“%d “,sta.st_blocks);//文件所占块数
printf(“%s “,&sta.st_atime);//最近存取时间
printf(“%s “,&sta.st_mtime);//最近访问时间
printf(“%s \n”,ctime(sta.st_ctime));//最近修改时间
*/
//st_mode 用特征位来表示文件类型及权限的,2个字节16位的二进制数
//(0-8)权限,(9-11)id,(12-15)类型,6位的八进制数,八进制数以0开头
printf(“%c”,file_type(sta.st_mode & S_IFMT));//与标准相与
strcpy(buf,check_rights(sta.st_mode));//打印权限
printf(“%s “,buf);
printf(“%d “,sta.st_nlink);
// /etc目录下的passwd文件包含所有用户所有信息(struct passwd)
// 以结构体形式逐条存放,name,passwd,uid,gid,comment,home,shell
pw=getpwuid(sta.st_uid);
printf(“%s “,pw->pw_name);

        gr=getgrgid(sta.st_gid);
        printf("%s ",gr->gr_name);

        printf("%6d ",sta.st_size);//大小

        t=localtime(&sta.st_ctime);
        printf("%d月 %d %02d:%02d\t ",(t->tm_mon)+1,t->tm_mday,t->tm_hour,t->tm_min);
        //printf("%s",ctime(&sta.st_ctime));//ctime将时间和日期转换成字符串

        printf("%s\n",the->d_name);
    }
}

closedir(dirp);

}
char file_type(mode_t s)
{
char c;
switch(s)
{
case S_IFBLK: c=’b’;break;
case S_IFSOCK: c=’s’;break;
case S_IFLNK: c=’l’;break;
case S_IFREG: c=’-‘;break;
case S_IFDIR: c=’d’;break;
case S_IFCHR: c=’c’;break;
case S_IFIFO: c=’p’;break;
default:c=’?’;
}
return c;
}
char* check_rights(mode_t s)
{
static char buf[10];
buf[9]=’\0’;
if(s & 0000001)//按位与判断是否有相应权限,按位或给与相应权限
buf[8]=’x’;
else
buf[8]=’-‘;
if(s & 0000002)
buf[7]=’w’;
else
buf[7]=’-‘;
if(s & 0000004)
buf[6]=’r’;
else
buf[6]=’-‘;

if(s & 0000001<<3)//按位与判断是否有相应权限,按位或给与相应权限
        buf[5]='x';
else
        buf[5]='-';
if(s & 0000002<<3)
        buf[4]='w';
else
        buf[4]='-';
if(s & 0000004<<3)
        buf[3]='r';
else
        buf[3]='-';

if(s & 0000001<<6)//按位与判断是否有相应权限,按位或给与相应权限
        buf[2]='x';
else
        buf[2]='-';
if(s & 0000002<<6)
        buf[1]='w';
else
        buf[1]='-';
if(s & 0000004<<6)
        buf[0]='r';
else
        buf[0]='-';
return buf;

}

“`

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章