#include #include #include #include #include #include #define COMMAND_MAX_SIZE 512 //maximalni delka retezce, kterou je mozno nacist od uzivatele vcetne \0 extern int errno; struct dir_tree { struct dir_tree * prev; struct dir_tree * next; struct dirent * file; }; typedef enum { UNKNOWN, HELP, LS, CD, CAT, EXIT } prikaz; /** * Vraci cislo prikazu nacteneho od uzivatele. Pokud ma prikaz argument, * nacte se do parametru command. */ prikaz readcommand(char * command) { prikaz navrat = UNKNOWN; printf("$ "); scanf("%s",command); if(!strcmp("help",command)) navrat = HELP; else if(!strcmp("ls",command)) navrat = LS; else if(!strcmp("dir",command)) navrat = LS; else if(!strcmp("exit",command)) navrat = EXIT; else if(!strcmp("quit",command)) navrat = EXIT; else if(!strcmp("cd",command)) navrat = CD; else if(!strcmp("cat",command)) navrat = CAT; if(navrat == CD || navrat == CAT) { // nactu argument scanf("%s",command); } else { // zadny argument command[0] = '\0'; } return navrat; } // FUNKCE SPRACOVAVAJICI PRIKAZY void command_help(struct dir_tree * rootdir, char * arg) { printf("NÁPOVĚDA\n" "Program můžete ovládat následujícími příkazy:\n" "help - vypíše tuto nápovědu\n" "ls - vypíše název souboru\n" "cd - přejde do zadaného adresáře\n" "cat - vypíše zadaný soubor\n" "exit - ukončí program\n" "\n"); } /** * nacte zdany adresar a ulozi jeho strukturu do spojoveho seznamu dir_tree */ void command_cd(struct dir_tree * rootdir,char * adresar) { struct dir_tree * helpdir1; DIR *str_dir; struct dirent * d; // pokusime se zmenit aktualni adresar if(chdir(adresar)) { perror("chdir"); return; } // pokud dir_tree obsahuje nejake polozky, uvolnime je while(rootdir->next != NULL) { helpdir1 = rootdir->next->next; free(rootdir->next->file); free(rootdir->next); rootdir->next = helpdir1; } // nacteni adresare str_dir = opendir("."); if(str_dir == NULL) { perror("opendir"); return; } while(d = readdir(str_dir)) { helpdir1 = (struct dir_tree *) malloc(sizeof(struct dir_tree)); if(!helpdir1) { printf("Nedostatek paměti!\n"); break; } helpdir1->file = (struct dirent *) malloc(sizeof(struct dirent)); if(!helpdir1->file) { printf("Nedostatek paměti!\n"); break; } helpdir1->prev = rootdir; helpdir1->next = NULL; *(helpdir1->file) = *d; rootdir->next = helpdir1; rootdir = rootdir->next; //printf("nacitam %s\n",helpdir1->file->d_name); } if(closedir(str_dir)) perror("closedir"); } /** * Vypise na obrazovku obsah aktualniho adresare * */ void command_ls(struct dir_tree * rootdir,char * arg) { printf("type\tinode\tsize\tname\n"); while(rootdir->next) { rootdir = rootdir->next; printf("%i\t%i\t%i\t%s\n", rootdir->file->d_type, rootdir->file->d_ino, rootdir->file->d_reclen, rootdir->file->d_name); } } void command_cat(struct dir_tree * rootdir,char * filename) { FILE * f; char sbuffer[512]; size_t nacteno; if(!(f = fopen(filename,"r"))) { perror("fopen"); return; } while(!feof(f)) { if(!(nacteno = fread(sbuffer,sizeof(char),sizeof(sbuffer)-1,f))) { perror("fread"); break; } sbuffer[nacteno] = '\0'; printf("%s",sbuffer); } if(fclose(f)) perror("fclose"); } int main(void) { struct dir_tree rootdir = {NULL,NULL,NULL}; prikaz p; char command[COMMAND_MAX_SIZE]; printf("Vítejte v du č.1!\n" "----------------\n"); command_cd(&rootdir,"."); command_help(&rootdir, NULL); do { p = readcommand(command); switch(p) { case HELP: command_help(&rootdir,command); break; case CD: command_cd(&rootdir,command); break; case LS: command_ls(&rootdir,command); break; case CAT: command_cat(&rootdir,command); break; case UNKNOWN: default: printf("Neznámý příkaz! Zadejte help pro nápovědu.\n"); break; case EXIT: printf("Nashledanou!\n"); break; } } while(p != EXIT); return 0; }