Własny ls, funkcja rekurencyjna

0

Witam, piszę tutaj ponieważ mam pewien problem. Piszę własnego "el-esa", program listujący dany katalog. Moja wersja ma działać na takiej zasadzie, że jeśli napotka na plik to wyświetla jego szczegóły, jeśli to folder to przechodzi dalej listując go i robiąc to samo z elementami tego folderu. Coś na zasadzie windowsowego tree, lecz ze szczegółami dla plików. Niby wszystko napisałem, jest funkcja rekurencyjna lecz nie działa poprawnie. Po przejściu do danego folderu funkcja nie radzi sobie z jego elementami. Liczyłem ilość wykonań tej funkcji, testowałem dla różnych sytuacji lecz nie mogę samodzielnie dojść do źródła problemu. Może wynika to ze zbyt małej wiedzy o samych funkcjach jakie używam, nie wiem, proszę o pomoc.

#include<sys/stat.h>
#include<stdio.h>
#include<dirent.h>


void permissions(mode_t tryby){
	if(tryby & S_IRUSR) printf("r");else printf("-");
    if(tryby & S_IWUSR) printf("w");else printf("-");
    if(tryby & S_IXUSR) printf("x");else printf("-");
    if(tryby & S_IRGRP) printf("r");else printf("-");
    if(tryby & S_IWGRP) printf("w");else printf("-");
    if(tryby & S_IXGRP) printf("x");else printf("-");
    if(tryby & S_IROTH) printf("r");else printf("-");
    if(tryby & S_IWOTH) printf("w");else printf("-");
    if(tryby & S_IXOTH) printf("x");else printf("-");
}

void type(mode_t tryby){
	if(S_ISDIR(tryby))printf("folder");
    if(S_ISREG(tryby))printf("zwykly plik");
    if(S_ISLNK(tryby))printf("dowiazanie symboliczne");
    if(S_ISFIFO(tryby))printf("fifo");
}

void file_info(struct stat file, mode_t tryby, char *filename){
	printf("\n\t Plik %s:\n\n", filename);
	printf("Uprawnienia_____: ");
	permissions(tryby);
	printf("\nTyp pliku_______: ");
	type(tryby);
	printf("\nData utworzenia_: %d", file.st_ctime);
	printf("\nData modyfikacji: %d", file.st_mtime);
	printf("\nWlasciciel______: %d", file.st_uid);
	printf("\nRozmiar pliku___: %d bajtow\n", file.st_size);
}

void tree(char *filename){
	struct stat file;
    struct dirent *dr;
    DIR *directory;
    mode_t tryby;
    
	if(lstat(filename,&file)==-1)
   		return;
    if((directory=opendir(filename))==NULL){
    	tryby=file.st_mode;
    	file_info(file,tryby,filename);
    }
    else{
    	printf("\n In directory -> %s\n", filename);
    	while(dr=readdir(directory)){
        	if(dr->d_ino != 0)
            	if(dr->d_name[0]!='.' && dr->d_name[1]!='.')
            		tree(dr->d_name);
        }
    }
}

int main(int argc, char *argv[]){
    if(argc <  2){
    	printf("Podaj sciezke do pliku/katalogu\n\n");
        return 0;
    }
    tree(argv[1]);
	return 0;
} 
0

Po co jest ten while i czym się różnią kolejne wywołania readdir(directory) ?

0

Dla każdego wykonania pętli while do 'dr->d_name' podstawia jeden z listowanych elementów z danego 'directory'.

0

Może w tree(dr->d_name); powinieś podawać też ścieżkę do aktualnie obrabianego folderu, bo inaczej program myśli, że plik o nazwie dr->d_name znajduje się w tym folderze co program?

0

Hmm, jakby to wytłumaczyć, to nie działa w ten sposób. Jeśli funkcja przejdzie do folderu i działa na plikach w nim, to ścieżki się zgadzają, bo sam 'filename' nie zawiera tylko nazwy pliku/folderu, lecz nazwę z pełną ścieżką (np. plik w ~/ o nazwie 'file' pod zmienną 'filename' wygląda : /home/%usr%/file). Sama linia z warunkiem 'directory=opendir(filename)' sprawdza czy można otworzyć folder o nazwie/ścieżce 'filename', jeśli tak to pod wskaźnik typu DIR ustawia tę otwartą ścieżkę, jeśli nie to wyświetla tylko informacje o pliku, bo skoro nie można było otworzyć, to oznacza to, że jest to jakis plik.

1 użytkowników online, w tym zalogowanych: 0, gości: 1