嵌入式學習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;

}

“`

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