#include #include #include #include #include #include #include #include // Stale przechowujace format wyswietlanej daty oraz daty z godzina #define DATE_FORMAT "%d-%m-%Y" #define DATE_TIME_FORMAT "%d %B %Y roku o %X" // Struktura przechowujaca wszystkie informacje na temat pliku, ktore ponzeniej typedef struct fileSystemNode { char type; char permission[16]; char owner[128]; char group[128]; long size; int linkCount; time_t lastUpdateTimestamp; time_t lastAccessTimestamp; time_t lastStateChangeTimestamp; char name[512]; char filename[1024]; short isExecutable; short isSymLink; short isDirectory; } fsNode; // Funkcja porownujaca napisy wykorzystywana przy sortowaniu int stringComparator(const fsNode*a, const fsNode*b) { return strcmp(a->name, b->name); } // Funkcja formatujaca date/czas do wyswietlenia, funkcja zwraca wartosc poprzez podany wskaznik // (zwracana wartosc podobnie jak w funkcji scanf) void formatTime(time_t t, char *output, char *format) { struct tm lt; localtime_r(&t, <); strftime(output, 64, format, <); } // Funkcja odczytujaca za pomoca funkcji stat informacje o pliku i wpisujaca je do struktury fsNode fsNode getFsNode(const char *path,const char *name) { struct stat S; char filename[512]; sprintf(filename, "%s/%s", path, name); stat(filename, &S); char perm[16]; sprintf(perm, "%c%c%c%c%c%c%c%c%c", ((S.st_mode & S_IRUSR) ? 'r' : '-'), ((S.st_mode & S_IWUSR) ? 'w' : '-'), ((S.st_mode & S_IXUSR) ? 'x' : '-'), ((S.st_mode & S_IRGRP) ? 'r' : '-'), ((S.st_mode & S_IWGRP) ? 'w' : '-'), ((S.st_mode & S_IXGRP) ? 'x' : '-'), ((S.st_mode & S_IROTH) ? 'r' : '-'), ((S.st_mode & S_IWOTH) ? 'w' : '-'), ((S.st_mode & S_IXOTH) ? 'x' : '-')); struct group *gr = getgrgid(S.st_gid); struct passwd *user = getpwuid(S.st_uid); fsNode fileNode; strcpy(fileNode.name, name); strcpy(fileNode.filename, filename); strcpy(fileNode.owner, user->pw_name); strcpy(fileNode.group, gr->gr_name); strcpy(fileNode.permission, perm); fileNode.type = ((S_ISDIR(S.st_mode)) ? 'd' : '-'); fileNode.size = S.st_size; fileNode.linkCount = S.st_nlink; fileNode.lastUpdateTimestamp = S.st_mtime; fileNode.lastAccessTimestamp = S.st_atime; fileNode.lastStateChangeTimestamp = S.st_ctime; fileNode.isExecutable = (S.st_mode & S_IXUSR) || (S.st_mode & S_IXGRP) || (S.st_mode & S_IXOTH); fileNode.isSymLink = (S_ISLNK(S.st_mode)) ? 1 : 0; fileNode.isDirectory = (S_ISDIR(S.st_mode)) ? 1 : 0; return fileNode; } // Funkcja drukujaca listing zawartosci katalogu - TRYB 1 void printDir(char *path) { DIR *mydir; struct dirent *myfile; mydir = opendir(path); int i = 0; fsNode nodes[128]; while ((myfile = readdir(mydir)) != NULL) { nodes[i] = getFsNode(path, myfile->d_name); i++; } qsort( nodes, i, sizeof(fsNode),( int( * )( const void *, const void * ) ) stringComparator); int j = 0; char formattedTime[64]; while (j < i) { formatTime(nodes[j].lastUpdateTimestamp, formattedTime, DATE_FORMAT); printf("%c%s %3d %10s %10s %8ld %s %s\n", nodes[j].type, nodes[j].permission, nodes[j].linkCount, nodes[j].owner, nodes[j].group, nodes[j].size, formattedTime, nodes[j].name); j++; } closedir(mydir); } // Funkcja drukujaca szczegoly dla zadanego pliku - TRYB 2 void printDetails(const char *path,const char *name) { fsNode fileNode = getFsNode(path, name); printf("Informacje o pliku:\nTyp pliku: "); if (fileNode.isSymLink) { printf("link symboliczny\n"); } else if (fileNode.isDirectory) { printf("katalog\n"); } else { printf("zwykly plik\n"); } printf("Sciezka: %s\n", fileNode.filename); printf("Rozmiar: %ld bajtow\n", fileNode.size); printf("Uprawnienia: %s\n", fileNode.permission); char formattedTime[64]; formatTime(fileNode.lastAccessTimestamp, formattedTime, DATE_TIME_FORMAT); printf("Ostatnio uzywany: %s\n", formattedTime); formatTime(fileNode.lastUpdateTimestamp, formattedTime, DATE_TIME_FORMAT); printf("Ostatnio modyfikowany: %s\n", formattedTime); formatTime(fileNode.lastStateChangeTimestamp, formattedTime, DATE_TIME_FORMAT); printf("Ostatnio zmieniany stan: %s\n", formattedTime); if (!fileNode.isExecutable) { printf("Poczatek zawartosci: \n"); FILE *file = fopen(fileNode.filename, "r"); char contents[512]; int i = 2; while (fgets(contents, sizeof(contents), file) && i-- > 0) { printf("%s", contents); } } } // Przekazanie parametrow wejsciowych do odpowiednich funkcji int main(int argc, const char *argv[]) { if (argc == 1) { printDir("."); } else if (argc == 2) { printDetails(".", argv[1]); } else { perror("Unsupported operation"); } return 0; }