| /********************************************************************************* | 
|  *      Copyright:  (C) 2023 LingYun IoT System Studio. | 
|  *                  All rights reserved. | 
|  * | 
|  *       Filename:  mycp.c | 
|  *    Description:  This file is ls command example code. | 
|  * | 
|  *        Version:  1.0.0(2023年08月08日) | 
|  *         Author:  Guo Wenxue <guowenxue@gmail.com> | 
|  *      ChangeLog:  1, Release initial version on "2023年08月08日 17时17分00秒" | 
|  * | 
|  ********************************************************************************/ | 
|   | 
| #include <stdio.h> | 
| #include <stdlib.h> | 
| #include <string.h> | 
| #include <errno.h> | 
| #include <unistd.h> | 
| #include <dirent.h> | 
| #include <time.h> | 
| #include <pwd.h> | 
| #include <grp.h> | 
| #include <sys/types.h> | 
| #include <sys/stat.h> | 
|   | 
| #define PROGNAME        "myls" | 
|   | 
| static int myls(char *path); | 
|   | 
| int main (int argc, char **argv) | 
| { | 
|     int           fd; | 
|     int           i; | 
|   | 
|     if( 1 == argc ) | 
|     { | 
|         myls("."); | 
|         return 0; | 
|     } | 
|   | 
|     for(i=1; i<argc; i++) | 
|     { | 
|         myls(argv[i]); | 
|     } | 
|   | 
|     return 0; | 
| } | 
|   | 
| void print_filemode(mode_t mode) | 
| { | 
|     /* print file type */ | 
|     if( S_ISREG(mode) ) | 
|     { | 
|         printf("-"); | 
|     } | 
|     else if( S_ISDIR(mode) ) | 
|     { | 
|         printf("d"); | 
|     } | 
|     else if( S_ISCHR(mode) ) | 
|     { | 
|         printf("c"); | 
|     } | 
|     else if( S_ISBLK(mode) ) | 
|     { | 
|         printf("b"); | 
|     } | 
|     else if( S_ISFIFO(mode) ) | 
|     { | 
|         printf("f"); | 
|     } | 
|     else if( S_ISLNK(mode) ) | 
|     { | 
|         printf("l"); | 
|     } | 
|     else if( S_ISSOCK(mode) ) | 
|     { | 
|         printf("s"); | 
|     } | 
|   | 
|     /* print file mode  */ | 
|     printf("%c", (S_IRUSR&mode) ? 'r' : '-'); | 
|     printf("%c", (S_IWUSR&mode) ? 'w' : '-'); | 
|     printf("%c", (S_IXUSR&mode) ? 'x' : '-'); | 
|   | 
|     printf("%c", (S_IRGRP&mode) ? 'r' : '-'); | 
|     printf("%c", (S_IWGRP&mode) ? 'w' : '-'); | 
|     printf("%c", (S_IXGRP&mode) ? 'x' : '-'); | 
|   | 
|     printf("%c", (S_IROTH&mode) ? 'r' : '-'); | 
|     printf("%c", (S_IWOTH&mode) ? 'w' : '-'); | 
|     printf("%c", (S_IXOTH&mode) ? 'x' : '-'); | 
|   | 
|     printf(" "); | 
|   | 
|     return ; | 
| } | 
|   | 
| int print_info(char *file) | 
| { | 
|     struct stat   sbuf; | 
|     struct passwd *u; | 
|     struct group  *g; | 
|     time_t         t; | 
|     struct tm     *ptm; | 
|     char           mtime[32]; | 
|   | 
|     stat(file, &sbuf); | 
|   | 
|     print_filemode(sbuf.st_mode); | 
|   | 
|     /* print number of hard links  */ | 
|     printf("%2lu ", sbuf.st_nlink); | 
|   | 
|     /* print user name or user id */ | 
|     u = getpwuid (sbuf.st_uid); | 
|     if( u ) | 
|         printf("%s ", u->pw_name); | 
|     else | 
|         printf("%d ", sbuf.st_uid); | 
|   | 
|     /* print group name or group id */ | 
|     g = getgrgid (sbuf.st_gid); | 
|     if( g ) | 
|         printf("%s ", g->gr_name); | 
|     else | 
|         printf("%d ", sbuf.st_uid); | 
|   | 
|     /* print file size  */ | 
|     printf("%6lu ", sbuf.st_size); | 
|   | 
|     /* print time of last modification, Time functions: | 
|      *    https://www.jianshu.com/p/e92ced44f216 | 
|      *    https://blog.csdn.net/chen1415886044/article/details/106883544 | 
|      */ | 
|     t = (time_t)sbuf.st_mtim.tv_sec; | 
|     ptm = localtime(&t); | 
|     strftime(mtime, sizeof(mtime), "%b %e %R", ptm); | 
|     printf("%s ", mtime); | 
|   | 
|     printf("%s", file); | 
|   | 
|     printf("\n"); | 
|   | 
|     return 0; | 
| } | 
|   | 
| int myls(char *path) | 
| { | 
|     struct stat    sbuf; | 
|     DIR           *dirp; | 
|     struct dirent *dir; | 
|     char           filepath[512]; | 
|   | 
|     /* Check file exist or not */ | 
|     if( access(path, F_OK) ) | 
|     { | 
|         printf("%s: cannot access '%s': %s\n", PROGNAME, path, strerror(errno)); | 
|         return -2; | 
|     } | 
|   | 
|     stat(path, &sbuf); | 
|   | 
|     /* list file */ | 
|     if( !S_ISDIR(sbuf.st_mode) ) | 
|     { | 
|         print_info(path); | 
|         return 0; | 
|     } | 
|   | 
|     /* list folder */ | 
|     dirp = opendir(path); | 
|     if( !dirp ) | 
|     { | 
|         printf("%s: cannot open directory '%s': %s\n", PROGNAME, path, strerror(errno)); | 
|         return -3; | 
|     } | 
|   | 
|     while( NULL != (dir=readdir(dirp)) ) | 
|     { | 
|         if( !strcmp(path, ".") ) | 
|             strncpy(filepath, dir->d_name, sizeof(filepath)); | 
|         else | 
|             snprintf(filepath, sizeof(filepath), "%s/%s", path, dir->d_name); | 
|   | 
|         print_info(filepath); | 
|     } | 
|   | 
|     return 0; | 
| } |