/* ls3.c * purpose list contents of directory or directories * action if no args, use . else list files in args * note uses stat and pwd.h and grp.h * BUG: try ls3 /tmp */ #include #include #include #include #include #include #include "mode_to_letters.h" #include "gid_to_name.h" #include "show_file_info.h" #include "uid_to_name.h" void do_ls(char[]); void dostat(char *, char *); int main(int ac, char *av[]) { if ( ac == 1 ) do_ls( "." ); else while ( --ac ){ printf("%s:\n", *++av ); do_ls( *av ); } } void do_ls( char dirname[] ) /* * List files in directory called dirname */ { DIR *dir_ptr; // Directory pointer struct dirent *direntp; // Each entry in directory if ( (dir_ptr = opendir(dirname)) == NULL ) // Open directory { fprintf(stderr, "ls3: cannot open %s\n", dirname); } else { // Read each entry in the directory while ( (direntp = readdir(dir_ptr)) != NULL ) { // Skip . and .. directories if ( strcmp(direntp->d_name, ".") == 0 || strcmp(direntp->d_name, "..") == 0 ) continue; // Construct the full path char *full_path = (char *)malloc(strlen(dirname) + strlen(direntp->d_name) + 2); // +2 for '/' and '\0' if (!full_path) { fprintf(stderr, "Memory allocation error\n"); closedir(dir_ptr); return; } // Concatenate the directory path and file name if (dirname[strlen(dirname) - 1] == '/') // If dirname ends with '/', just concatenate sprintf(full_path, "%s%s", dirname, direntp->d_name); else // If dirname doesn't end with '/', add a '/' sprintf(full_path, "%s/%s", dirname, direntp->d_name); // Call dostat to display file info dostat(full_path, direntp->d_name); // Free the allocated memory for full_path free(full_path); } closedir(dir_ptr); } } void dostat( char *full_path, char *filename ) { struct stat info; if ( stat(full_path, &info) == -1 ) // Cannot stat file perror(filename); // Show error else // Show file info show_file_info(filename, &info); }