#include #include #include #include #include #include #include #include #include void dispMode (int); void scand (char *); int inode_flag = 0; int all_flag = 0; int long_flag = 0; int rec_flag = 0; main (int argc, char *argv[]) { int n; int i, j; struct dirent **namelist; struct stat buf; char dir[30]; char tempfile[30]; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') //option { for (j = 1; j < strlen (argv[i]); j++) { if (argv[i][j] == 'l') //long long_flag = 1; else if (argv[i][j] == 'i') //inode inode_flag = 1; else if (argv[i][j] == 'a') //all files all_flag = 1; else if (argv[i][j] == 'r') //recursive rec_flag = 1; else { printf("ls: invalid option -- %c\n",argv[i][j]); printf("Try \'ls --help\' for more information.\n"); exit(0); } } } } if (argc != 1) { if (argv[argc - 1][0] != '-') //directory specified strcpy (dir, argv[argc - 1]); else strcpy (dir, "."); //else current directory } else strcpy (dir, "."); scand (dir); } //function to display mode in frwxrwxrwx format void dispMode (int m) { char mode[11]; if (m & S_IFREG) //file mode[0] = '-'; else if (m & S_IFDIR) //dir mode[0] = 'd'; else if (m & S_IFLNK) //link mode[0] = 'l'; else if (m & S_IFBLK) //block mode[0] = 'b'; else if (m & S_IFCHR) //char mode[0] = 'c'; else if (m & S_IFIFO) //fifo mode[0] = 'f'; //user permissions mode[1] = (m & S_IRUSR) ? 'r' : '-'; mode[2] = (m & S_IWUSR) ? 'w' : '-'; mode[3] = (m & S_IXUSR) ? 'x' : '-'; //group permissions mode[4] = (m & S_IRGRP) ? 'r' : '-'; mode[5] = (m & S_IWGRP) ? 'w' : '-'; mode[6] = (m & S_IXGRP) ? 'x' : '-'; //others permissions mode[7] = (m & S_IROTH) ? 'r' : '-'; mode[8] = (m & S_IWOTH) ? 'w' : '-'; mode[9] = (m & S_IXOTH) ? 'x' : '-'; mode[10] = '\0'; printf ("%s", mode); } void scand (char *dir) { int i, n; char tempfile[1000]; struct dirent **namelist; struct passwd *pwd; struct group *grp; struct stat buf; char *timestr; int j; n = scandir (dir, &namelist, 0, alphasort); //scan directory if (n < 0) perror ("scandir"); else { if (rec_flag) printf ("\n%s: \n", dir); if (all_flag) // '-a' option specified i = 0; else i = 2; strcat (dir, "/"); while (i < n) { strcpy (tempfile, dir); strcat (tempfile, namelist[i]->d_name); //path+file stat (tempfile, &buf); if (!all_flag) // 'a' option not used, ../ should be included if ((namelist[i]->d_name[0] == '.') && (isalnum (namelist[i]->d_name[1]))) { i++; continue; } if (inode_flag) // '-i' option specified printf ("%7d ", buf.st_ino); if (long_flag) // '-l' option specified { dispMode (buf.st_mode); // frwxrwxrwx printf ("%5d ", buf.st_nlink); //links pwd = getpwuid (buf.st_uid); //user printf ("%-9s", pwd->pw_name); //user grp = getgrgid (buf.st_gid); //group printf ("%-9s", grp->gr_name); //group printf ("%8d ", buf.st_size); //file size timestr = ctime (&buf.st_ctime); //last changed time for (j = 4; j < 16; j++) printf ("%c", timestr[j]); printf (" "); } printf ("%s ", namelist[i]->d_name); //filename if ((inode_flag && (i + 2) % 3 == 0) || (long_flag)) printf ("\n"); i++; } if (rec_flag) { if (all_flag) // '-a' option specified i = 0; else i = 2; while (i < n) { strcpy (tempfile, dir); strcat (tempfile, namelist[i]->d_name); //path+file stat (tempfile, &buf); if (S_ISDIR (buf.st_mode)) { scand (tempfile); } i++; } } printf ("\n"); free (namelist); } }