我用的时sentos
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
void power(int m, char s[])
{
strcpy(s, "----------");//首先将表示权限的字符串进行初始化
if(S_ISDIR(m))//利用宏判断此文件是否是一个目录
{
s[0]='d';//是则将其表示为有目录属性
}
if(S_ISCHR(m))//是否是字符设备
{
s[0]='c';
}
if(S_ISBLK(m))//是否是块设备
{
s[0]='b';
}
if((m&S_IRUSR))//检测mode,判断文件所有者是否有读权限
{
s[1]='r';
}
if((m&S_IWUSR))//文件所有者是否有写权限
{
s[2]='w';
}
if((m&S_IXUSR))//文件所有者是否有执行权限
{
s[3]='x';
}
if((m&S_IRGRP))//用户组是否有读权限
{
s[4]='r';
}
if((m&S_IWGRP))//用户组是否有写权限
{
s[5]='w';
}
if((m&S_IXGRP))//用户组是否有执行权限
{
s[6]='x';
}
if((m&S_IROTH))//其他用户是否有读权限
{
s[7]='r';
}
if((m&S_IWOTH))//其他用户是否有写权限
{
s[8]='w';
}
if((m&S_IXOTH))//其他用户是否有执行权限
{
s[9]='x';
}
}
char* uname(uid_t uid)
{
struct passwd* getpwuid(),* pw;//保存寻找到的用户信息
static char str[10];//保存用户名或者uid
if((pw=getpwuid(uid))==NULL)//通过用户名寻找密码,即寻找该用户,并利用该用户创建pw
{
sprintf(str,"%d",uid);//没找到则将uid格式化后存入str中并且返回该数组
return str;//返回uid
}
else
{
return pw->pw_name;//否则返回用户名
}
}
char* gname(gid_t gid)
{
struct group* getgrgid(),* g;//保存组信息
static char str[10];//保存组名或者gid
if((g=getgrgid(gid))==NULL)//通过gid寻找组
{
sprintf(str,"%d",gid);//没找到则将gid格式化后存入numstr中
return str;//返回gid
}
else
{
return g->gr_name;//找到则返回组名
}
}
void ifdir(char dirname[])
{
DIR* dir;
struct dirent* dire;//存储目录中的文件信息
if((dir=opendir(dirname))==NULL)//如果目录为空则显示错误信息,并利用dirname创建dir结构
{
fprintf(stderr, "can not open %s \n", dirname);
}
else
{
while((dire=readdir(dir))!=NULL)//只要目录中还有文件
{
creastat(dire->d_name);//传送文件名
}
close(dir);//关闭目录指针
}
}
void creastat(char* fname)
{
struct stat sta;
//用传送过来的文件名初始化stat结构
if(stat(fname,&sta)==-1)//失败
{
perror(fname);//显示错误信息
}
else//成功则开始获取并显示文件信息
{
show(fname, &sta);
}
}
void show(char* fname, struct stat* sta)
{
char* uname(), *ctime(), *gname(), *filemode();
char powe[11];//存储用户权限的字符串
power(sta->st_mode, powe);//判断文件权限,并存入modestr
printf("%s", powe);//显示文件各种权限
printf(" %4d", (int)sta->st_nlink);//连接此文件的连接数
printf(" %-8s", uname(sta->st_uid));//显示用户名
printf(" %-8s", gname(sta->st_gid));//显示组名
printf(" %8ld", (long)sta->st_size);//显示文件大小
printf(" %.12s",ctime(&sta->st_mtime));//最近修改的时间
printf(" %s\n", fname);//文件名
}
int main(int ac,char* av[])//ac获得命令行参数个数,av保存参数地址
{
if(ac==1)
{
ifdir(".");//传入当前目录
}
else
{
while(--ac)
{
printf("%s: \n",++*av);
ifdir(*av);//传入当前目录
}
}
}
下面时运行结果
以下时代码中使用的数据结构与宏的总结
2.重要数据结构的总结:
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //inode节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的连接数
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //伟建内容对应的块数量
};保存文件相关信息
struct dirent
{
long d_ino; /* inode number 索引节点号 */
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
} 该结构可以只想目录也可以只想普通文件,但在上述实现代码中是指向目录
struct passwd
{
char * pw_name; /* 用户名*/
char * pw_passwd; /* 密码 */
__uid_t pw_uid; /* 用户id */
__gid_t pw_gid; /* 组id */
char * pw_gecos; /* 描述*/
char * pw_dir; /* 主目录 */
char * pw_shell; /* 所属进程shell*/
}; 保存某一个用户的信息, struct group保存用户组信息,与这个结构体类似
3.重要宏总结
S_ISDIR(st_mode):是否是一个目录
S_ISCHR(st_mode):是否是一个字符设备.
S_ISBLK(st_mode):是否是一个块设备
S_IRUSR//文件所有者是否有读权限
S_IWUSR//文件所有者是否有写权限
S_IXUSR//文件所有者是否有执行权限
S_IRGRP//用户组是否有读权限
S_IWGRP//用户组是否有写权限
S_IXGRP//用户组是否有执行权限