-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathls_3.cpp
More file actions
118 lines (104 loc) · 3.22 KB
/
ls_3.cpp
File metadata and controls
118 lines (104 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <ctime>
#include <vector>
#include <algorithm>
// Function to print file details
void print_file_details(const char* filename, const struct stat& file_stat) {
// Print file type
if (S_ISREG(file_stat.st_mode)) {
std::cout << "-";
} else if (S_ISDIR(file_stat.st_mode)) {
std::cout << "d";
} else if (S_ISLNK(file_stat.st_mode)) {
std::cout << "l";
} else {
std::cout << "?";
}
// Print permissions
const char* permissions = "rwxrwxrwx";
for (int i = 0; i < 9; i++) {
if ((file_stat.st_mode >> (8 - i)) & 1) {
std::cout << permissions[i];
} else {
std::cout << "-";
}
}
// Print owner and group
struct passwd* owner_info = getpwuid(file_stat.st_uid);
struct group* group_info = getgrgid(file_stat.st_gid);
if (owner_info != nullptr) {
std::cout << " " << owner_info->pw_name;
} else {
std::cout << " " << file_stat.st_uid;
}
if (group_info != nullptr) {
std::cout << " " << group_info->gr_name;
} else {
std::cout << " " << file_stat.st_gid;
}
// Print file size
std::cout << " " << file_stat.st_size;
// Print last modification time
char time_buffer[80];
strftime(time_buffer, sizeof(time_buffer), "%b %d %H:%M", localtime(&file_stat.st_mtime));
std::cout << " " << time_buffer;
// Print filename
std::cout << " " << filename << std::endl;
}
int main(int argc, char *argv[]) {
const char* dir_path = ".";
int flags = 0; // Flags for -a and -l
// Parse command-line arguments
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-a") == 0) {
flags |= 1; // Set the first bit for -a
} else if (strcmp(argv[i], "-l") == 0) {
flags |= 2; // Set the second bit for -l
} else {
dir_path = argv[i];
}
}
// Open the directory
DIR* dir = opendir(dir_path);
if (dir == nullptr) {
perror("opendir");
return 1;
}
// Read directory entries
struct dirent* entry;
std::vector<std::string> filenames;
while ((entry = readdir(dir)) != nullptr) {
if (!(flags & 1) && entry->d_name[0] == '.') {
continue; // Skip hidden files if -a flag is not set
}
filenames.push_back(entry->d_name);
}
// Sort filenames alphabetically
std::sort(filenames.begin(), filenames.end());
// Display file details if -l flag is set, otherwise just print filenames
if (flags & 2) {
for (const std::string& filename : filenames) {
struct stat file_stat;
std::string full_path = std::string(dir_path) + "/" + filename;
if (lstat(full_path.c_str(), &file_stat) == 0) {
print_file_details(filename.c_str(), file_stat);
} else {
perror("lstat");
}
}
} else {
for (const std::string& filename : filenames) {
std::cout << filename << " ";
}
std::cout << std::endl;
}
closedir(dir);
return 0;
}