diff --git a/.vscode/settings.json b/.vscode/settings.json index bb4c6e0..992aed0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { - "C_Cpp.errorSquiggles": "Enabled" + "C_Cpp.errorSquiggles": "Enabled", + "files.associations": { + "ext2.h": "c" + } } diff --git a/EXT2/ext2.h b/EXT2/ext2.h index 50e3c03..4e6f4aa 100644 --- a/EXT2/ext2.h +++ b/EXT2/ext2.h @@ -1,3 +1,16 @@ +/** + * @file ext2.h + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * + * @brief arquivo de cabeçalho no qual estão definidas as estrutras usadas pelo EXT2 + * @version 0.5 + * @date 2022-12-02 + * + * + */ + #pragma once #include @@ -10,127 +23,150 @@ #define EXT2_NAME_LEN 255 +/** + * @brief estrutura do Superbloco, contém todas as informações sobre a configuração + * do sistema de arquivos. + * + */ struct ext2_super_block { - uint32_t s_inodes_count; /* Inodes count */ - uint32_t s_blocks_count; /* Blocks count */ - uint32_t s_r_blocks_count; /* Reserved blocks count */ - uint32_t s_free_blocks_count; /* Free blocks count */ - uint32_t s_free_inodes_count; /* Free inodes count */ - uint32_t s_first_data_block; /* First Data Block */ - uint32_t s_log_block_size; /* Block size */ - uint32_t s_log_frag_size; /* Fragment size */ - uint32_t s_blocks_per_group; /* # Blocks per group */ - uint32_t s_frags_per_group; /* # Fragments per group */ - uint32_t s_inodes_per_group; /* # Inodes per group */ - uint32_t s_mtime; /* Mount time */ - uint32_t s_wtime; /* Write time */ - uint16_t s_mnt_count; /* Mount count */ - uint16_t s_max_mnt_count; /* Maximal mount count */ - uint16_t s_magic; /* Magic signature */ - uint16_t s_state; /* File system state */ - uint16_t s_errors; /* Behaviour when detecting errors */ - uint16_t s_minor_rev_level; /* minor revision level */ - uint32_t s_lastcheck; /* time of last check */ - uint32_t s_checkinterval; /* max. time between checks */ - uint32_t s_creator_os; /* OS */ - uint32_t s_rev_level; /* Revision level */ - uint16_t s_def_resuid; /* Default uid for reserved blocks */ - uint16_t s_def_resgid; /* Default gid for reserved blocks */ - uint32_t s_first_ino; /* First non-reserved inode */ - uint16_t s_inode_size; /* size of inode structure */ - uint16_t s_block_group_nr; /* block group # of this superblock */ - uint32_t s_feature_compat; /* compatible feature set */ - uint32_t s_feature_incompat; /* incompatible feature set */ - uint32_t s_feature_ro_compat; /* readonly-compatible feature set */ - uint8_t s_uuid[16]; /* 128-bit uuid for volume */ - char s_volume_name[16]; /* volume name */ - char s_last_mounted[64]; /* directory where last mounted */ - uint32_t s_algorithm_usage_bitmap; /* For compression */ - uint8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ - uint8_t s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ + uint32_t s_inodes_count; /* número de inodes */ + uint32_t s_blocks_count; /* número de blocos */ + uint32_t s_r_blocks_count; /* número de blocos reservados */ + uint32_t s_free_blocks_count; /* número de blocos livres */ + uint32_t s_free_inodes_count; /* número de inodes livres */ + uint32_t s_first_data_block; /* identificador do primeiro bloco de dados */ + uint32_t s_log_block_size; /* tamanho do bloco */ + uint32_t s_log_frag_size; /* tamanho do fragmento */ + uint32_t s_blocks_per_group; /* blocos por grupo */ + uint32_t s_frags_per_group; /* fragmentos por grupo */ + uint32_t s_inodes_per_group; /* inodes por grupo */ + uint32_t s_mtime; /* última vez que o sistema foi montado */ + uint32_t s_wtime; /* último acesso de gravação ao sistema de arquivos */ + uint16_t s_mnt_count; /* quantas vezes o sistema foi montado desde desde a última verificação */ + uint16_t s_max_mnt_count; /* número máximo de vezes que o sistema de arquivos pode ser montado antes que uma verificação completa seja executada */ + uint16_t s_magic; /* identifica o sistema de arquivos como Ext2 */ + uint16_t s_state; /* estado do sistema de arquivos */ + uint16_t s_errors; /* o que fazer quando um erro é detectado */ + uint16_t s_minor_rev_level; /* nível de revisão secundário dentro de seu nível de revisão */ + uint32_t s_lastcheck; /* tempo da última verificação do sistema de arquivos */ + uint32_t s_checkinterval; /* intervalo de tempo máximo permitido entre as verificações do sistema de arquivos. */ + uint32_t s_creator_os; /* ID do sistema operacional que criou sistema de arquivos */ + uint32_t s_rev_level; /* nível de revisão */ + uint16_t s_def_resuid; /* ID de usuário padrão para blocos reservados */ + uint16_t s_def_resgid; /* ID de grupo padrão para blocos reservados */ + uint32_t s_first_ino; /* índice para o primeiro inode utilizável para arquivos padrão */ + uint16_t s_inode_size; /* tamanho da estrutura do inode */ + uint16_t s_block_group_nr; /* úmero do grupo de blocos que hospeda essa estrutura superbloco. */ + uint32_t s_feature_compat; /* máscara de 32 bits de recursos compatíveis */ + uint32_t s_feature_incompat; /* máscara de 32 bits de recursos incompatíveis */ + uint32_t s_feature_ro_compat; /* máscara de 32 bits de recursos “somente leitura" */ + uint8_t s_uuid[16]; /* ID do volume */ + char s_volume_name[16]; /* nome do volume */ + char s_last_mounted[64]; /* diretório onde o sistema de arquivos foi montado pela última vez */ + uint32_t s_algorithm_usage_bitmap; /* métodos de compactação usados */ + uint8_t s_prealloc_blocks; /* número de blocos que a implementação deve tentar pré-alocar ao criar um novo arquivo regular */ + uint8_t s_prealloc_dir_blocks; /* número de blocos que a implementação deve tentar pré-alocar ao criar um novo diretório */ uint16_t s_padding1; - uint8_t s_journal_uuid[16]; /* uuid of journal superblock */ - uint32_t s_journal_inum; /* inode number of journal file */ - uint32_t s_journal_dev; /* device number of journal file */ - uint32_t s_last_orphan; /* start of list of inodes to delete */ - uint32_t s_hash_seed[4]; /* HTREE hash seed */ - uint8_t s_def_hash_version; /* Default hash version to use */ + uint8_t s_journal_uuid[16]; /* uuid do superbloco de diário */ + uint32_t s_journal_inum; /* número de inode do arquivo de diário */ + uint32_t s_journal_dev; /* número de dispositivo do arquivo de diário */ + uint32_t s_last_orphan; /* primeiro inode na lista de inodes a serem excluídos */ + uint32_t s_hash_seed[4]; /* algoritmo de hash para indexação de diretório */ + uint8_t s_def_hash_version; /* versão de hash padrão usada para indexação de diretório. */ uint8_t s_reserved_char_pad; uint16_t s_reserved_word_pad; - uint32_t s_default_mount_opts; - uint32_t s_first_meta_bg; /* First metablock block group */ - uint32_t s_reserved[190]; /* Padding to the end of the block */ + uint32_t s_default_mount_opts; /* opções de montagem padrão para este sistema de arquivos */ + uint32_t s_first_meta_bg; /* ID do grupo de blocos do primeiro metagrupo de blocos */ + uint32_t s_reserved[190]; /* preenchimento até o final do bloco */ }ext2_super_block; +/** + * @brief estrutra do Descritor do Grupo de Blocos, contém informações sobre onde + * as estruturas de dados importantes para esse grupo de bloco estão localizadas + * + */ struct ext2_group_desc { - uint32_t bg_block_bitmap; /* Blocks bitmap block */ - uint32_t bg_inode_bitmap; /* Inodes bitmap block */ - uint32_t bg_inode_table; /* Inodes table block */ - uint16_t bg_free_blocks_count; /* Free blocks count */ - uint16_t bg_free_inodes_count; /* Free inodes count */ - uint16_t bg_used_dirs_count; /* Directories count */ - uint16_t bg_pad; - uint32_t bg_reserved[3]; + uint32_t bg_block_bitmap; /* endereço do bloco do bitmap de uso do bloco */ + uint32_t bg_inode_bitmap; /* endereço do bloco do bitmap de uso do inode */ + uint32_t bg_inode_table; /* endereço do bloco inicial da tabela de inodes */ + uint16_t bg_free_blocks_count; /* úmero total de blocos livres no grupo*/ + uint16_t bg_free_inodes_count; /* número total de inodes livres no grupo */ + uint16_t bg_used_dirs_count; /* número total de diretórios */ + uint16_t bg_pad; /* preencher a estrutura em um limite de 32 bits */ + uint32_t bg_reserved[3]; /* espaço reservado para futuras revisões */ }ext2_group_desc; + +/** + * @brief estrutura do inode, contém ponteiros para os blocos do sistema de arquivos e + * e os metadados de um objeto. + * + */ struct ext2_inode { - uint16_t i_mode; /* File mode */ - uint16_t i_uid; /* Low 16 bits of Owner Uid */ - uint32_t i_size; /* Size in bytes */ - uint32_t i_atime; /* Access time */ - uint32_t i_ctime; /* Creation time */ - uint32_t i_mtime; /* Modification time */ - uint32_t i_dtime; /* Deletion Time */ - uint16_t i_gid; /* Low 16 bits of Group Id */ - uint16_t i_links_count; /* Links count */ - uint32_t i_blocks; /* Blocks count */ - uint32_t i_flags; /* File flags */ + uint16_t i_mode; /* formato do arquivo descrito e os direitos de acesso */ + uint16_t i_uid; /* ID de usuário de 16 bits associado ao arquivo */ + uint32_t i_size; /* tamanho do arquivo em bytes */ + uint32_t i_atime; /* hora do último acesso */ + uint32_t i_ctime; /* tempo de criação */ + uint32_t i_mtime; /* última vez que foi modificado */ + uint32_t i_dtime; /* tempo de exclusão */ + uint16_t i_gid; /* ID do grupo */ + uint16_t i_links_count; /* contagem de hard links */ + uint32_t i_blocks; /* número total de blocos */ + uint32_t i_flags; /* sinalizadores de arquivo */ union { struct { - uint32_t l_i_reserved1; + uint32_t l_i_reserved1; /* valor de 32 bits atualmente reservado */ } linux1; struct { - uint32_t h_i_translator; + uint32_t h_i_translator; /* tradutor */ } hurd1; struct { - uint32_t m_i_reserved1; + uint32_t m_i_reserved1; /* valor de 32 bits atualmente reservado */ } masix1; - } osd1; /* OS dependent 1 */ - uint32_t i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ - uint32_t i_generation; /* File version (for NFS) */ - uint32_t i_file_acl; /* File ACL */ - uint32_t i_dir_acl; /* Directory ACL */ - uint32_t i_faddr; /* Fragment address */ + } osd1; /* estrutura dependente do sistema operacional de 32 bits */ + + uint32_t i_block[EXT2_N_BLOCKS];/* ponteiros para os blocos */ + uint32_t i_generation; /* versão de arquivo */ + uint32_t i_file_acl; /* arquivo ACL */ + uint32_t i_dir_acl; /* diretório ACL */ + uint32_t i_faddr; /* endereço de fragmento */ union { struct { - uint8_t l_i_frag; /* Fragment number */ - uint8_t l_i_fsize; /* Fragment size */ - uint16_t i_pad1; - uint16_t l_i_uid_high; /* these 2 fields */ - uint16_t l_i_gid_high; /* were reserved2[0] */ - uint32_t l_i_reserved2; + uint8_t l_i_frag; /* número de fragmento */ + uint8_t l_i_fsize; /* tamanho de fragmento */ + uint16_t i_pad1; + uint16_t l_i_uid_high; /* id de usuário */ + uint16_t l_i_gid_high; /* de id de gruppo */ + uint32_t l_i_reserved2; /* reservado */ } linux2; + struct { - uint8_t h_i_frag; /* Fragment number */ - uint8_t h_i_fsize; /* Fragment size */ - uint16_t h_i_mode_high; - uint16_t h_i_uid_high; - uint16_t h_i_gid_high; - uint32_t h_i_author; + uint8_t h_i_frag; /* número do fragmento */ + uint8_t h_i_fsize; /* tamanho do fragmento */ + uint16_t h_i_mode_high; /* alto 16 bits do modo de 32 bits */ + uint16_t h_i_uid_high; /* id de usuário */ + uint16_t h_i_gid_high; /* id de grupo */ + uint32_t h_i_author; /* ID de usuário do autor do arquivo atribuído */ } hurd2; + struct { - uint8_t m_i_frag; /* Fragment number */ - uint8_t m_i_fsize; /* Fragment size */ - uint16_t m_pad1; - uint32_t m_i_reserved2[2]; + uint8_t m_i_frag; /* número do fragmento */ + uint8_t m_i_fsize; /* tamanho do fragmento */ + uint16_t m_pad1; + uint32_t m_i_reserved2[2]; /* reservado */ } masix2; - } osd2; /* OS dependent 2 */ + } osd2; /* estrutura dependente do sistema operacional de 64 bits */ }ext2_inode; +/** + * @brief estrutura da entrada de diretórios na tabela de inodes + * + */ struct ext2_dir_entry_2 { - uint32_t inode; /* Inode number */ - uint16_t rec_len; /* Directory entry length */ - uint8_t name_len; /* Name length */ - uint8_t file_type; - char name[EXT2_NAME_LEN]; /* File name, up to EXT2_NAME_LEN */ + uint32_t inode; /* número de inode */ + uint16_t rec_len; /* tamanho total desta entrada */ + uint8_t name_len; /* comprimento de nome */ + uint8_t file_type; /* tipo de arquivo */ + char name[EXT2_NAME_LEN]; /* nome do arquivo */ }ext2_dir_entry_2; \ No newline at end of file diff --git a/ListDirEntry/listDirEntry.c b/ListDirEntry/listDirEntry.c index 68a8e49..7e67da3 100644 --- a/ListDirEntry/listDirEntry.c +++ b/ListDirEntry/listDirEntry.c @@ -1,18 +1,33 @@ +/** + * @file listDirEntry.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de implementação das funções de manipulação das estruturas + * @version 0.1 + * @date 2022-12-17 + * + * + */ #include "listDirEntry.h" ListDirEntry* createListDirEntry() { - ListDirEntry* list = (ListDirEntry*)malloc(sizeof(ListDirEntry)); - list->head = NULL; - list->tail = NULL; + ListDirEntry* list = (ListDirEntry*)malloc(sizeof(ListDirEntry)); /* alocação */ + + /****incialização das variáveis da struct*****/ + list->head = NULL; + list->tail = NULL; list->qtdDirEntries = 0; list->amountOfCluster = 0; - return list; + + return list; /* retorna a struct */ } static struct ext2_dir_entry_2* insertInTheLastPosition(ListDirEntry* list, NodeDirEntry* entry) { - struct NodeDirEntry* aux = list->head; + + struct NodeDirEntry* aux = list->head; /* pega o que está no "topo" da lista */ // Procura pelo fim da lista de DirEntry while (aux->next != NULL) { @@ -23,7 +38,7 @@ static struct ext2_dir_entry_2* insertInTheLastPosition(ListDirEntry* list, entry->previous = aux; aux->next = entry; - return entry->entry; + return entry->entry; /* retorna diretório de entrada */ } void removeLastDirEntry(ListDirEntry* list) { @@ -49,9 +64,9 @@ void removeLastDirEntry(ListDirEntry* list) { free(aux->entry); free(aux); - list->qtdDirEntries--; + list->qtdDirEntries--; /* atualiza contador*/ - if (list->qtdDirEntries == 0) { + if (list->qtdDirEntries == 0) { /* caso não tenho mais diretórios */ list->tail = NULL; list->head = NULL; }; diff --git a/ListDirEntry/listDirEntry.h b/ListDirEntry/listDirEntry.h index c55f096..acb3624 100644 --- a/ListDirEntry/listDirEntry.h +++ b/ListDirEntry/listDirEntry.h @@ -1,3 +1,15 @@ +/** + * @file listDirEntry.h + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de declaração das funções de manipulação das estruturas + * @version 0.1 + * @date 2022-12-17 + * + * + */ + #pragma once #include #include @@ -5,6 +17,11 @@ #include "../EXT2/ext2.h" + +/** + * @brief struct dos diretórios de entrada + * + */ typedef struct NodeDirEntry { struct NodeDirEntry* next; struct NodeDirEntry* previous; @@ -12,6 +29,10 @@ typedef struct NodeDirEntry { uint32_t cluster; } NodeDirEntry; +/** + * @brief struct da lista de diretórios de entrada + * + */ typedef struct ListDirEntry { int qtdDirEntries; int amountOfCluster; @@ -19,7 +40,39 @@ typedef struct ListDirEntry { struct NodeDirEntry* tail; } ListDirEntry; +/** + * @brief cria um ListDirEntry + * + * @return ListDirEntry* + */ ListDirEntry* createListDirEntry(); + + + +/** + * @brief inserte diretório na lista + * + * @param list onde será inserida + * @param entry diretório de entrada que será inserido + * @param position + * @return struct ext2_dir_entry_2* + */ struct ext2_dir_entry_2* insertDirEntry(ListDirEntry* list, NodeDirEntry* entry, int* position); + + + +/** + * @brief destrói a struct ListDirEntry referenciada + * + * @param list struct ListDirEntry referenciada + */ void destroyListDirEntry(ListDirEntry* list); + + + +/** + * @brief remove o último diretório da lista + * + * @param list + */ void removeLastDirEntry(ListDirEntry* list); \ No newline at end of file diff --git a/Makefile b/Makefile index faf723a..7e00399 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ all: gcc -g -c utils/utils.c gcc -g -c main.c + gcc -g -c StackDirectory/stackDirectory.c + gcc -g -c ListDirEntry/listDirEntry.c gcc -g -c commands/attr/attr.c gcc -g -c commands/cat/cat.c gcc -g -c commands/cd/cd.c diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..3786870 --- /dev/null +++ b/README.txt @@ -0,0 +1,17 @@ +Compilação: + Para realizar a compilação, basta digitar o comando make pelo terminal. + +Execução: + Para executar, o processo é análogo à compilação, porém, o comando a ser utilizado é o ./main myext2image.img, + ao inserir este comando um shell será inicicializado. + +Bibliotecas: + + : providencia configurações de tipo integer cujas definições são consistenentes em + diferentes máquinas e Sindependente de Sistemass Operacionais ou outras implementações. + + : declara configurações de tipos integer contendo larguras especificadas, e define + configurações correspondentes de macros. Também de define macros que especificam limites de + tipos integer de outros cabeçalhos. + + : define as estruturas de dados retornadas pelas funções fstat(), lstat() e stat(). diff --git a/StackDirectory/stackDirectory.c b/StackDirectory/stackDirectory.c index 4f9a0ef..6368817 100644 --- a/StackDirectory/stackDirectory.c +++ b/StackDirectory/stackDirectory.c @@ -1,3 +1,15 @@ +/** + * @file stackDirectory.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de implementação das funções de manipulação da estrutura StackDirectory + * @version 0.1 + * @date 2022-12-17 + * + * + */ + #include "stackDirectory.h" StackDirectory* createStackDirectory() { @@ -30,7 +42,7 @@ void push(StackDirectory* stack, NodeStackDirectory* node, char* name) { stack->currentDirectory = node; } - stack->qtdDirectory++; + stack->qtdDirectory++; /* atualiza contador incrementando */ } void pop(StackDirectory* stack) { @@ -48,7 +60,7 @@ void pop(StackDirectory* stack) { destroyListDirEntry(node->listDirEntry); free(node); - stack->qtdDirectory--; + stack->qtdDirectory--; /* atualiza contador decrementando */ } void destroyStack(StackDirectory* stack) { @@ -61,4 +73,3 @@ void destroyStack(StackDirectory* stack) { free(stack); } - diff --git a/StackDirectory/stackDirectory.h b/StackDirectory/stackDirectory.h index 421b3de..1022b47 100644 --- a/StackDirectory/stackDirectory.h +++ b/StackDirectory/stackDirectory.h @@ -1,10 +1,28 @@ +/** + * @file stackDirectory.h + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de declaração das funções de manipulação da estrutura StackDirectory + * @version 0.1 + * @date 2022-12-17 + * + * + */ + #pragma once #include #include #include #include "../ListDirEntry/listDirEntry.h" +#include "../utils/utils.h" +/** + * @brief struct que contém informações importantes sobre + * o diretório sendo referenciado + * + */ typedef struct NodeStackDirectory { struct NodeStackDirectory* next; struct NodeStackDirectory* previous; @@ -12,14 +30,60 @@ typedef struct NodeStackDirectory { char name[20]; } NodeStackDirectory; +/** + * @brief struct da pilha de diretórios, ou seja, o armazenamento + * + */ typedef struct StackDirectory { int qtdDirectory; struct NodeStackDirectory* currentDirectory; struct NodeStackDirectory* rootDirectory; } StackDirectory; -StackDirectory* createStackDirectory(); +/** + * @brief cria uma struct StackDirectory + * + * @return struct StackDirectory* + */ +struct StackDirectory* createStackDirectory(); + + + +/** + * @brief adiciona node no topo da pilha + * + * @param stack StackDirectory onde o node será armazenado + * @param node que será adicionado + * @param name nome do node + */ void push(StackDirectory* stack, NodeStackDirectory* node, char* name); + + + +/** + * @brief remove node do topo da pilha + * + * @param stack StackDirectory do qual o node do topo será retirado + */ void pop(StackDirectory* stack); + + + +/** + * @brief destrói StackDiretory + * + * @param stack tackDirectory que será destruído + */ void destroyStack(StackDirectory* stack); -void readAllDirectoryAndPushIntoStack(); + + + +/** + * @brief + * + * @param file + * @param gdesc + * @param super + * @param stack + */ +void readAllDirectoryAndPushIntoStack(FILE* file, struct ext2_group_desc* gdesc, struct ext2_super_block* super, struct StackDirectory* stack); diff --git a/commands/attr/attr.c b/commands/attr/attr.c index e69de29..3cd4d08 100644 --- a/commands/attr/attr.c +++ b/commands/attr/attr.c @@ -0,0 +1,125 @@ +/** + * @file attr.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de implementação das funções usadas para o comando attr + * @version 0.4 + * @date 2022-11-15 + * + */ + +#include "attr.h" + +void attrCommand(FILE* file, struct ext2_inode inode, struct ext2_group_desc *group, struct ext2_super_block* super, char* file_name){ + uint32_t inode_no = read_dir(file, &inode, group, file_name); + + if(!inode_no) return; + + read_inode(file, inode_no, group, &inode, super); + + int mode = inode.i_mode; /* formato e atributos do inode */ + char file_type, + user_read, + user_write, + user_execute, + group_read, + group_write, + group_execute, + others_read, + others_write, + others_execute; + + /* verifica o tipo do arquivo */ + if(mode & 0x4000) file_type = 'd'; + if(mode & 0x8000) file_type = 'f'; + + // ================ user fields ============== + if(mode & 0x0100){ + user_read = 'r'; + } else { + user_read = '-'; + } + + if(mode & 0x0080){ + user_write = 'w'; + }else { + user_write = '-'; + } + + if(mode & 0x0040){ + user_execute = 'x'; + }else { + user_execute = '-'; + } + + // ================ groud fields ============== + if(mode & 0x0100){ + group_read = 'r'; + } else { + group_read = '-'; + } + + if(mode & 0x0080){ + group_write = 'w'; + }else { + group_write = '-'; + } + + if(mode & 0x0040){ + group_execute = 'x'; + }else { + group_execute = '-'; + } + + // ================ others fields ============== + if(mode & 0x0100){ + others_read = 'r'; + } else { + others_read = '-'; + } + + if(mode & 0x0080){ + others_write = 'w'; + }else { + others_write = '-'; + } + + if(mode & 0x0040){ + others_execute = 'x'; + }else { + others_execute = '-'; + } + + float size; + char* size_text; + + /* tamanho do arquivo */ + if(inode.i_size < 1024){ + size = inode.i_size; + size_text = "Bytes"; + }else { + size = inode.i_size / 1024; + size_text = "KiB"; + } + + char* mtime = convertNumToUnixTime(inode.i_mtime); /* hora da montagem */ + + printf("permissões\tuid\tgid\ttamanho\t\tmodificado em\n"); /* exibe informações do arquivo */ + printf("%c%c%c%c%c%c%c%c%c%c\t%u\t%u\t%.2f %s\t%s\n", + file_type, + user_read, + user_write, + user_execute, + group_read, + group_write, + group_execute, + others_read, + others_write, + others_execute, + inode.i_uid, + inode.i_gid, + size, + size_text, + mtime); +} \ No newline at end of file diff --git a/commands/attr/attr.h b/commands/attr/attr.h index e69de29..bc6708b 100644 --- a/commands/attr/attr.h +++ b/commands/attr/attr.h @@ -0,0 +1,26 @@ +/** + * @file attr.h + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de declaração da função usada para o comando attr + * @version 0.4 + * @date 2022-11-15 + * + */ + +#pragma once + +#include "../../EXT2/ext2.h" +#include "../../utils/utils.h" + +/** + * @brief exibe atributos de um arquivo ou diretório + * + * @param file imagem do sistema + * @param inode + * @param group Fescritor de Grupo de Blocos + * @param super superbloco + * @param file_name nome do arquivo + */ +void attrCommand(FILE* file, struct ext2_inode inode, struct ext2_group_desc *group, struct ext2_super_block* super, char* file_name); diff --git a/commands/cat/cat.c b/commands/cat/cat.c index e69de29..bf7f43d 100644 --- a/commands/cat/cat.c +++ b/commands/cat/cat.c @@ -0,0 +1,30 @@ +/** + * @file cat.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginal Gregorio de Souza Neto + * @brief arquivo de implementação da função usada para o comando cat + * @version 0.1 + * @date 2022-12-16 + * + */ + +#include "cat.h" + +void catCommand(FILE* file, struct ext2_inode inode, struct ext2_group_desc *group, struct ext2_super_block* super, char* file_name){ + uint32_t inode_no = read_dir(file, &inode, group, file_name); + read_inode(file, inode_no, group, &inode, super); + + if(!inode_no) return; + + unsigned char block[BLOCK_SIZE]; + + if(inode.i_mode & 0x4000){ + printf(RED("ERROR:") " comando" CYAN(" cat ") "funciona apenas com arquivos.\n"); + }else { + fseek(file, BLOCK_OFFSET(inode.i_block[0]), SEEK_SET); /* posiciona ponteiro do imagem do sistema */ + fread(block, BLOCK_SIZE, 1, file); /* acessa conteúdo do arruivo*/ + + printf("%s", block); /* exibe conteúdo */ + } +} \ No newline at end of file diff --git a/commands/cat/cat.h b/commands/cat/cat.h index e69de29..500639b 100644 --- a/commands/cat/cat.h +++ b/commands/cat/cat.h @@ -0,0 +1,26 @@ +/** + * @file attr.h + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de declaração da função usada para o comando cat + * @version 0.6 + * @date 2022-12-15 + * + */ + +#pragma once + +#include "../../EXT2/ext2.h" +#include "../../utils/utils.h" + +/** + * @brief exibe conteúdo do arquivo no formato de texto + * + * @param file imagem do sistema + * @param inode + * @param group Descritor de Grupo de Blocos + * @param super superbloco + * @param file_name nome do arquivo + */ +void catCommand(FILE* file, struct ext2_inode inode, struct ext2_group_desc *group, struct ext2_super_block* super, char* file_name); diff --git a/commands/cd/cd.c b/commands/cd/cd.c index e69de29..0bd737f 100644 --- a/commands/cd/cd.c +++ b/commands/cd/cd.c @@ -0,0 +1,61 @@ +/** + * @file cd.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de implementação da função que realiza o comando cd + * @version 0.1 + * @date 2022-12-16 + * + */ + + +#include "cd.h" + +void cdCommand(FILE* file, struct ext2_inode *inode, struct ext2_group_desc *group, char* nomeArquivo){ + void *block; + + if (S_ISDIR(inode->i_mode)) { /* verifica se é diretório */ + struct ext2_dir_entry_2 *entry; + unsigned int size = 0; + + if ((block = malloc(BLOCK_SIZE)) == NULL) { /* aloca memória para o boco de dados */ + fprintf(stderr, "Memory error\n"); + fclose(file); + exit(1); + } + + fseek(file, BLOCK_OFFSET(inode->i_block[0]), SEEK_SET); /* posiciona ponteiro da imagem */ + fread(block, BLOCK_SIZE, 1, file); /* lê bloco do disco */ + + entry = (struct ext2_dir_entry_2 *) block; /* primeira entrada no diretório */ + + int found_file = 0; + + while((size < inode->i_size) && entry->inode) { + char file_name[EXT2_NAME_LEN+1]; + memcpy(file_name, entry->name, entry->name_len); /* copia nome do arquivo para a variável de comparação */ + file_name[entry->name_len] = 0; /* caractere nulo para o nome de arquivo */ + if(strcmp(nomeArquivo, file_name) == 0){ /* verifica se arquivo foi encontrado */ + + if(entry->file_type == 2){ /* verifica se a entrda é do tipo diretório */ + printf("%s\n", entry->name); + printf("inode: %u\n", entry->inode); + printf("record lenght: %u\n", entry->rec_len); + printf("name lenght: %u\n", entry->name_len); + printf("file type: %u\n", entry->file_type); + } else{ + printf("Não é um diretório\n"); + } + + } + // printf("%10u %s\n", entry->inode, file_name); + entry = (void*) entry + entry->rec_len; + size += entry->rec_len; + } + + if(!found_file) printf(RED("Arquivo ou diretório inexistente")); /* informa caso o arquivo não foi encontrado */ + printf("\n"); + free(block); /* libera bloco alocado */ + } +} \ No newline at end of file diff --git a/commands/cd/cd.h b/commands/cd/cd.h index c2cddda..90d3d8f 100644 --- a/commands/cd/cd.h +++ b/commands/cd/cd.h @@ -1,3 +1,16 @@ +/** + * @file cd.h + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author + * @brief + * @version 0.1 + * @date 2022-12-16 + * + * @copyright Copyright (c) 2022 + * + */ + #pragma once #include @@ -8,4 +21,12 @@ #include "../../utils/utils.h" #include "../pwd/pwd.h" -int cdCommand(); \ No newline at end of file +/** + * @brief função que realiza o comando cp + * + * @param file + * @param inode + * @param group + * @param nomeArquivo + */ +void cdCommand(FILE* file, struct ext2_inode *inode, struct ext2_group_desc *group, char* nomeArquivo); \ No newline at end of file diff --git a/commands/info/info.c b/commands/info/info.c index e6415a5..d45431a 100644 --- a/commands/info/info.c +++ b/commands/info/info.c @@ -1,12 +1,27 @@ +/** + * @file info.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de implementação da função usada para o comando info + * @version 0.1 + * @date 2022-12-16 + * + */ + #include "info.h" void infoCommand(struct ext2_super_block* super){ - uint32_t image_size = super->s_blocks_count * super->s_log_block_size; - uint32_t free_space = (super->s_free_blocks_count * super->s_log_block_size) / 1024; - uint32_t groups_count = 1 + (super->s_blocks_count-1) / super->s_blocks_per_group; - uint32_t inodetable_size = (super->s_inodes_per_group * super->s_inode_size) / 1024; + uint32_t image_size = super->s_blocks_count * super->s_log_block_size; /* tamnho da imagem */ + uint32_t free_space = (super->s_free_blocks_count * super->s_log_block_size) / 1024; /* quantidade de espaço livre */ + uint32_t groups_count = 1 + (super->s_blocks_count-1) / super->s_blocks_per_group; /* quantidade de grupos de blocos */ + uint32_t inodetable_size = (super->s_inodes_per_group * super->s_inode_size) / 1024; /* tamnho da tabela de inodes */ printf("\n"); + + /* a partir da estrutura do super bloco passada como parâmetro as informações são acessadas e exibidas, + * além de também exibir as informações obtidas a partir dos cáculos feitos a cima + */ printf("Volume name.....: %s\n" "Image size......: %" PRIu32 " bytes\n" "Free space......: %" PRIu32 " KiB\n" @@ -19,7 +34,7 @@ void infoCommand(struct ext2_super_block* super){ "Groups inodes...: %" PRIu32 " inodes\n" "Inodetable size.: %" PRIu32 " blocks\n" , - super->s_volume_name, + super->s_volume_name, image_size, free_space, super->s_free_inodes_count, diff --git a/commands/info/info.h b/commands/info/info.h index 1f871cf..46dbb04 100644 --- a/commands/info/info.h +++ b/commands/info/info.h @@ -1,3 +1,14 @@ +/** + * @file info.h + * @author Iago Ortega Carmona + * @author Thiago GAriani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de declaração da função usada para o comando info + * @version 0.1 + * @date 2022-12-16 + * + */ + #pragma once #include #include @@ -5,4 +16,10 @@ #include "../../EXT2/ext2.h" +/** + * @brief função que por meio do parâmetro recebido irá exibir as informações referentes + * ao disco e ao sistema de arquivos + * + * @param super estrutura de dados do superbloco na qual é armazenada as informaçõe do sistema + */ void infoCommand(struct ext2_super_block* super); \ No newline at end of file diff --git a/commands/ls/ls.c b/commands/ls/ls.c index e69de29..285d07e 100644 --- a/commands/ls/ls.c +++ b/commands/ls/ls.c @@ -0,0 +1,40 @@ +/** + * @file ls.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de implemetação da função que realiza o comando ls + * @version 0.1 + * @date 2022-12-16 + * + * + */ + +#include "ls.h" + +void lsCommand(ListDirEntry *listDirEntry){ + struct NodeDirEntry* dirEntry = listDirEntry->head; + DirEntry* entry = dirEntry->entry; + + // se não tiver nada, apenas retorna + if (dirEntry == NULL) return; + + while(1){ + printf("\n"); + char file_name[EXT2_NAME_LEN+1]; + memcpy(file_name, entry->name, entry->name_len); + file_name[entry->name_len] = 0; + + printf("%s\n", file_name); + printf("inode: %d\n", entry->inode); + printf("record lenght: %d\n", entry->rec_len); + printf("name lenght: %d\n", entry->name_len); + printf("file type: %d\n", entry->file_type); + + // se chegou ao fim, finaliza + if (dirEntry->next == NULL) break; + + dirEntry = dirEntry->next; + entry = dirEntry->entry; + } +} \ No newline at end of file diff --git a/commands/ls/ls.h b/commands/ls/ls.h index e69de29..bfc15a2 100644 --- a/commands/ls/ls.h +++ b/commands/ls/ls.h @@ -0,0 +1,21 @@ +/** + * @file ls.h + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de declaração da função que realiza o comando ls + * @version 0.1 + * @date 2022-12-17 + * + */ + +#pragma once + +#include "../../utils/utils.h" + +/** + * @brief função que realiza a execução do comando ls + * + * @param listDirEntry lista de entradas de diretórios + */ +void lsCommand(ListDirEntry *listDirEntry); \ No newline at end of file diff --git a/commands/pwd/pwd.c b/commands/pwd/pwd.c index 87ebf2e..b16f473 100644 --- a/commands/pwd/pwd.c +++ b/commands/pwd/pwd.c @@ -1 +1,29 @@ +/** + * @file pwd.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de implementação da função que executa o comando pwd + * @version 0.1 + * @date 2022-12-17 + * + * + */ + #include "pwd.h" + +char* pwdCommand(StackDirectory* stackDirectory){ + int size = (255 * stackDirectory->qtdDirectory) + stackDirectory->qtdDirectory; + char* output = (char*)calloc(size + 1, sizeof(char)); + + NodeStackDirectory* aux = stackDirectory->rootDirectory; /* aponta para diretório raiz */ + + for (int i = 0; i < stackDirectory->qtdDirectory; i++) { /* enquanto não chegar ao llimite de diretórios na pilha */ + strcat(output, aux->name); + if ((i + 1) != stackDirectory->qtdDirectory) { + if (i) strcat(output, "/"); /* anexa "/" ao final de output */ + aux = aux->next; /* aponta para próximo diretório */ + } + } + return output; +} \ No newline at end of file diff --git a/commands/pwd/pwd.h b/commands/pwd/pwd.h index 8ae26c9..fef9f4f 100644 --- a/commands/pwd/pwd.h +++ b/commands/pwd/pwd.h @@ -1,3 +1,15 @@ +/** + * @file pwd.h + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de declaração da função que realiza o comando pwd + * @version 0.1 + * @date 2022-12-16 + * + * + */ + #pragma once #include @@ -6,4 +18,10 @@ #include "../../StackDirectory/stackDirectory.h" -char* pwdCommand(struct StackDirectory* stackDirectory); \ No newline at end of file +/** + * @brief função que realiza a execução do comando pwd, que exibe o caminho absoluto + * + * @param stackDirectory pilha de diretórios + * @return char* + */ +char* pwdCommand(StackDirectory* stackDirectory); \ No newline at end of file diff --git a/main.c b/main.c index 487b039..b495d73 100644 --- a/main.c +++ b/main.c @@ -5,8 +5,11 @@ #include "EXT2/ext2.h" #include "utils/utils.h" +#include "StackDirectory/stackDirectory.h" #include "commands/help/help.h" #include "commands/info/info.h" +#include "commands/cat/cat.h" +#include "commands/attr/attr.h" int main(int argc, char **argv){ @@ -24,31 +27,37 @@ int main(int argc, char **argv){ } char buffer[1024]; - memset(buffer, '\0', sizeof(buffer)); + memset(buffer, '\0', sizeof(buffer)); /* reseta */ char **commands; - // initializing superblock struct + struct StackDirectory *stackDirectory = createStackDirectory(); /* cria estrtura de pilha de diretório */ + + /* incializando estrutura do superbloco */ struct ext2_super_block super; - // reading superblock + /* lendo superbloco */ read_super_block(file, &super); super.s_log_block_size = BLOCK_SIZE; super.s_log_frag_size = BLOCK_SIZE; - // initializing group descriptor struct + /* incializando estrutura do descritor de grupo */ struct ext2_group_desc gdesc[GROUP_COUNT]; - // reading group descriptor + /* lendo descritor de grupo */ read_group_descriptors(file, &super, gdesc); - // initializing inode strut + /* inicializando estrutura inode */ struct ext2_inode inode; - readAllDirectoryAndPushIntoStack(); + /* inicializando estrutura do diretório de entrada */ + struct ext2_dir_entry_2 dirEntry; + + read_inode(file, 2, gdesc, &inode, &super); + read_all_root_dirs(file, &inode, gdesc); - system("clear"); + // system("clear"); // char *pwd = pwdCommand(stackDirectory); - printf(GREEN("ext2shell:") BLUE("[myext2image/]") "$ "); + printf(GREEN("ext2shell:") BLUE("[/]") "$ "); while(fgets(buffer, 1024, stdin) != NULL){ int amountOfCommands = tokenize_array_of_commands(&commands, buffer, &amountOfCommands); @@ -92,15 +101,14 @@ int main(int argc, char **argv){ if (amountOfCommands != 2) { printf("Quantidade de argumentos inválidos para o comando attr.\n"); } else { - // attrCommand(stackDirectory->currentDirectory->listDirEntry, - // commands[1]); + attrCommand(file, inode, gdesc, &super, commands[1]); } } else if (!strcmp(commands[0], "cat")) { if (amountOfCommands != 2) { printf( - "Quantidade de argumentos inválidos para o comando cluster.\n"); + "Quantidade de argumentos inválidos para o comando cat.\n"); } else { - // cluster(bootSector, file, atoi(commands[1])); + catCommand(file, inode, gdesc, &super, commands[1]); } } else if (!strcmp(commands[0], "rename")) { if (amountOfCommands != 3) { @@ -143,7 +151,7 @@ int main(int argc, char **argv){ printf("Quantidade de argumentos inválidos para o comando print.\n"); } if(!strcmp(commands[1], "superblock")){ - print_super_block(super, BLOCK_SIZE); + print_super_block(&super, BLOCK_SIZE); } else if(!strcmp(commands[1], "groups")){ for(int i = 0; i < get_amount_groups_in_block(&super); i++){ print_group_descriptor(gdesc[i], i); @@ -154,7 +162,7 @@ int main(int argc, char **argv){ printf("Exemplo: " BLUE("print inode 2") "\n"); } else{ read_inode(file, atoi(commands[2]), gdesc, &inode, &super); - print_inode(inode); + print_inode(&inode); } } } else { @@ -167,7 +175,7 @@ int main(int argc, char **argv){ // file = fopen("myimagefat32.img", "rb+"); // destroy_array_of_commands(commands, amountOfCommands); - printf(GREEN("ext2shell:") BLUE("[img]") "$ "); + printf(GREEN("ext2shell:") BLUE("[/]") "$ "); } printf("\n"); diff --git a/myext2image.img b/myext2image.img index cc39c23..ff257b1 100644 Binary files a/myext2image.img and b/myext2image.img differ diff --git a/utils/utils.c b/utils/utils.c index 05fc569..d1dffd6 100644 --- a/utils/utils.c +++ b/utils/utils.c @@ -1,31 +1,43 @@ +/** + * @file utils.c + * @author Iago Ortega Carmona + * @author Thiago Gariani Quinto + * @author Reginal Gregorio de Souza Neto + * @brief arquivo de implmentação das funções recorrentes de uso + * @version 0.1 + * @date 2022-12-16 + * + * + */ + #include "utils.h" void read_super_block(FILE* file, struct ext2_super_block* super){ - fseek(file, 1024, SEEK_SET); - fread(super, sizeof(ext2_super_block), 1, file); + fseek(file, 1024, SEEK_SET); /* desloca ponteiro para a posição do superbloco */ + fread(super, sizeof(ext2_super_block), 1, file); /* lê os dados apontado por "file" e os armazenado em "super" */ } void read_group_descriptors(FILE* file, struct ext2_super_block* super, struct ext2_group_desc* gdesc){ - fseek(file, 1024 + super->s_log_block_size, SEEK_SET); + fseek(file, 1024 + super->s_log_block_size, SEEK_SET); /* desloca ponteiro da imagem do sistema de arquivos */ for(int i = 0; i < get_amount_groups_in_block(super); i++){ - fread(&gdesc[i], sizeof(ext2_group_desc), 1, file); + fread(&gdesc[i], sizeof(ext2_group_desc), 1, file); /* lê todos os Descritores de Grupo */ } } void read_inode(FILE* file, int inode_no, struct ext2_group_desc* gdesc, struct ext2_inode* inode, struct ext2_super_block* super){ - int offset = get_offset_of_inode_in_itable(super, gdesc, inode_no); - fseek(file, offset, SEEK_SET); - fread(inode, sizeof(ext2_inode), 1, file); + int offset = get_offset_of_inode_in_itable(super, gdesc, inode_no); /* pega offset de inode relacionao ao seu número */ + fseek(file, offset, SEEK_SET); /* desloca ponteiro da imagem de disco */ + fread(inode, sizeof(ext2_inode), 1, file); /* lê a informação a partir do ponteiro */ } int tokenize_array_of_commands(char ***commands, char *arg, int *amountOfCommands) { - int size = strlen(arg); + int size = strlen(arg); /* tamanho da string */ if (size < 1) return -1; char argsTokenized[size]; memset(argsTokenized, '\0', size); - strcpy(argsTokenized, arg); + strcpy(argsTokenized, arg); /* copia para argsTokenized o conteúdo de arg */ argsTokenized[size - 1] = '\0'; // Contando quantas strings devemos armazenar @@ -37,31 +49,34 @@ int tokenize_array_of_commands(char ***commands, char *arg, int *amountOfCommand token = strchr(token, ' '); } - char **tokenizedCommands = (char **)calloc(amountOfStrings, sizeof(char *)); + char **tokenizedCommands = (char **)calloc(amountOfStrings, sizeof(char *)); /* aloca espaço para os comandos em forma de tokens */ int i = 0; - token = strtok(argsTokenized, " "); + token = strtok(argsTokenized, " "); /* criar tokens com o delimitador " " */ char *buffer; while (token != 0x0) { - buffer = (char *)calloc(strlen(token) + 1, sizeof(char)); - strcpy(buffer, token); + buffer = (char *)calloc(strlen(token) + 1, sizeof(char)); /* aloca buffer com espaço para os tokens */ + strcpy(buffer, token); /* copia o contéudo de token para buffer */ tokenizedCommands[i++] = buffer; token = strtok(NULL, " "); } - *commands = tokenizedCommands; - return amountOfStrings; + *commands = tokenizedCommands; /* commands recebe o cnteúdo de tokenizedCommands */ + return amountOfStrings; /* retorna a quantidade de caracteres */ } void destroy_array_of_commands(char **commands, int amountOfCommands) { for (int i = 0; i < amountOfCommands; i++) { - free(commands[i]); + free(commands[i]); /* libera cado posição do vetor */ } - free(commands); + free(commands); /* libera o vetor */ } -void print_super_block(struct ext2_super_block super, unsigned int block_size){ +void print_super_block(struct ext2_super_block *super, unsigned int block_size){ + +/* acessa e exibe as informações do superbloco a partir da estrutura passa como argumento */ + printf("\n"); printf("inodes count.................: %" PRIu32 "\n" "blocks count.................: %" PRIu32 "\n" @@ -109,56 +124,59 @@ void print_super_block(struct ext2_super_block super, unsigned int block_size){ "default mount options........: %" PRIu32 "\n" "first meta...................: %" PRIu32 "\n" , - super.s_inodes_count, - super.s_blocks_count, - super.s_r_blocks_count, /* reserved blocks count */ - super.s_free_blocks_count, - super.s_free_inodes_count, - super.s_first_data_block, - super.s_log_block_size, - super.s_log_frag_size, - super.s_blocks_per_group, - super.s_frags_per_group, - super.s_inodes_per_group, - super.s_mtime, - super.s_wtime, - super.s_mnt_count, - super.s_max_mnt_count, - super.s_magic, - super.s_state, - super.s_errors, - super.s_minor_rev_level, - super.s_lastcheck, - super.s_checkinterval, - super.s_creator_os, - super.s_rev_level, - super.s_def_resuid, - super.s_def_resgid, - super.s_first_ino, /* first non-reserved inode */ - super.s_inode_size, - super.s_block_group_nr, - super.s_feature_compat, - super.s_feature_incompat, - super.s_feature_ro_compat, - super.s_uuid[0], - super.s_volume_name, - super.s_last_mounted, - super.s_algorithm_usage_bitmap, - super.s_prealloc_blocks, - super.s_prealloc_dir_blocks, - super.s_journal_uuid[0], - super.s_journal_inum, - super.s_journal_dev, - super.s_last_orphan, - super.s_hash_seed[0], - super.s_def_hash_version, - super.s_default_mount_opts, - super.s_first_meta_bg); + super->s_inodes_count, + super->s_blocks_count, + super->s_r_blocks_count, /* reserved blocks count */ + super->s_free_blocks_count, + super->s_free_inodes_count, + super->s_first_data_block, + super->s_log_block_size, + super->s_log_frag_size, + super->s_blocks_per_group, + super->s_frags_per_group, + super->s_inodes_per_group, + super->s_mtime, + super->s_wtime, + super->s_mnt_count, + super->s_max_mnt_count, + super->s_magic, + super->s_state, + super->s_errors, + super->s_minor_rev_level, + super->s_lastcheck, + super->s_checkinterval, + super->s_creator_os, + super->s_rev_level, + super->s_def_resuid, + super->s_def_resgid, + super->s_first_ino, /* first non-reserved inode */ + super->s_inode_size, + super->s_block_group_nr, + super->s_feature_compat, + super->s_feature_incompat, + super->s_feature_ro_compat, + super->s_uuid[0], + super->s_volume_name, + super->s_last_mounted, + super->s_algorithm_usage_bitmap, + super->s_prealloc_blocks, + super->s_prealloc_dir_blocks, + super->s_journal_uuid[0], + super->s_journal_inum, + super->s_journal_dev, + super->s_last_orphan, + super->s_hash_seed[0], + super->s_def_hash_version, + super->s_default_mount_opts, + super->s_first_meta_bg); printf("\n"); } void print_group_descriptor(struct ext2_group_desc gdesc, int i){ + +/* acessa e exibe as informações do Fescritor de Grupo de Blocos a partir da estrutura passa como argumento */ + printf("\n"); printf("block group descriptor.: %d\n" "block bitmap...........: %" PRIu32 "\n" @@ -178,7 +196,10 @@ void print_group_descriptor(struct ext2_group_desc gdesc, int i){ printf("\n"); } -void print_inode(struct ext2_inode inode){ +void print_inode(struct ext2_inode* inode){ + + /* acessa e exibe as informações do inode a partir da estrutura passa como argumento */ + printf("\n"); printf("file format and access rights....: %" PRIu16 "\n" "user id..........................: %" PRIu16 "\n" @@ -212,60 +233,146 @@ void print_inode(struct ext2_inode inode){ "higher 32-bit file size..........: %" PRIu32 "\n" "location file fragment...........: %" PRIu32 "\n" , - inode.i_mode, - inode.i_uid, - inode.i_size, - inode.i_atime, - inode.i_ctime, - inode.i_mtime, - inode.i_dtime, - inode.i_gid, - inode.i_links_count, - inode.i_blocks, - inode.i_flags, - inode.osd1.linux1.l_i_reserved1, - inode.i_block[0], - inode.i_block[1], - inode.i_block[2], - inode.i_block[3], - inode.i_block[4], - inode.i_block[5], - inode.i_block[6], - inode.i_block[7], - inode.i_block[8], - inode.i_block[9], - inode.i_block[10], - inode.i_block[11], - inode.i_block[12], - inode.i_block[13], - inode.i_block[14], - inode.i_generation, - inode.i_file_acl, - inode.i_dir_acl, - inode.i_faddr); + inode->i_mode, + inode->i_uid, + inode->i_size, + inode->i_atime, + inode->i_ctime, + inode->i_mtime, + inode->i_dtime, + inode->i_gid, + inode->i_links_count, + inode->i_blocks, + inode->i_flags, + inode->osd1.linux1.l_i_reserved1, + inode->i_block[0], + inode->i_block[1], + inode->i_block[2], + inode->i_block[3], + inode->i_block[4], + inode->i_block[5], + inode->i_block[6], + inode->i_block[7], + inode->i_block[8], + inode->i_block[9], + inode->i_block[10], + inode->i_block[11], + inode->i_block[12], + inode->i_block[13], + inode->i_block[14], + inode->i_generation, + inode->i_file_acl, + inode->i_dir_acl, + inode->i_faddr); printf("\n"); } int get_inode_group(struct ext2_super_block* super, int inode_no){ - int inodes_per_group = super->s_inodes_per_group; - return inode_no / inodes_per_group; + int inodes_per_group = super->s_inodes_per_group; /* variável recebe o número de inode por grupo */ + return inode_no / inodes_per_group; /* realiza a operação necessário para saber o o grupo do inode */ } int get_inodes_per_block(struct ext2_super_block* super){ - return super->s_log_block_size / super->s_inode_size; + return super->s_log_block_size / super->s_inode_size; /* realiza operação necessário para calcular o número de inodes por bloco*/ } int get_amount_groups_in_block(struct ext2_super_block* super){ - return 1 + (super->s_blocks_count-1) / super->s_blocks_per_group; + return 1 + (super->s_blocks_count-1) / super->s_blocks_per_group; /* realiza operação necessário para calcular o número de grupos por bloco*/ } int get_amount_inodes_in_itable(struct ext2_super_block* super){ - return super->s_inodes_per_group / get_inodes_per_block(super); + return super->s_inodes_per_group / get_inodes_per_block(super); /* calcula o número de inodes da tabela de inodes */ } int get_offset_of_inode_in_itable(struct ext2_super_block* super, struct ext2_group_desc* gdesc, int inode_no){ - int inode_group = get_inode_group(super, inode_no); - int inode_table = gdesc[inode_group].bg_inode_table; - int offset = BLOCK_OFFSET(inode_table)+(inode_no-1)*sizeof(struct ext2_inode) % super->s_inodes_per_group; - return offset; + int inode_group = get_inode_group(super, inode_no); /* recebe o grupo do inode */ + int inode_table = gdesc[inode_group].bg_inode_table; /* recebe a tabela de inodes */ + int offset = BLOCK_OFFSET(inode_table)+(inode_no-1)*sizeof(struct ext2_inode) % super->s_inodes_per_group; /* offset é calculado */ + return offset; /* retorna offset */ +} + +uint32_t read_dir(FILE* file, struct ext2_inode *inode, struct ext2_group_desc *group, char* nomeArquivo) +{ + void *block; + + if (S_ISDIR(inode->i_mode)) { + struct ext2_dir_entry_2 *entry; + unsigned int size = 0; + + if ((block = malloc(BLOCK_SIZE)) == NULL) { /* aloca memória para o boco de dados */ + fprintf(stderr, "Memory error\n"); + fclose(file); + exit(1); + } + + fseek(file, BLOCK_OFFSET(inode->i_block[0]), SEEK_SET); /* posiciona ponteiro da imagem */ + fread(block, BLOCK_SIZE, 1, file); /* lê bloco do disco */ + + entry = (struct ext2_dir_entry_2 *) block; /* primeira entrada no diretório */ + + int found_file = 0; + + while((size < inode->i_size) && entry->inode) { + char file_name[EXT2_NAME_LEN+1]; + memcpy(file_name, entry->name, entry->name_len); /* copia nome do arquivo para a variável de comparação */ + file_name[entry->name_len] = 0; /* caractere nulo para o nome de arquivo */ + if(strcmp(nomeArquivo, file_name) == 0){ /* verifica se arquivo foi encontrado */ + return entry->inode; /* retorna entrda */ + found_file = 1; /* indica que arquivo foi encontrado */ + }else{ + found_file = 0; /* arquivo não encontrado */ + } + // printf("%10u %s\n", entry->inode, file_name); + entry = (void*) entry + entry->rec_len; + size += entry->rec_len; + } + if(!found_file) printf(RED("file not found")); /* informa caso o arquivo não foi encontrado */ + printf("\n"); + free(block); /* libera bloco alocado */ + } +} + +void read_all_root_dirs(FILE* file, struct ext2_inode *inode, struct ext2_group_desc *group){ + void *block; + + struct ext2_dir_entry_2 *entry; + unsigned int size = 0; + + if ((block = malloc(BLOCK_SIZE)) == NULL) { /* aloca memória para o bloco de dados */ + fprintf(stderr, "Memory error\n"); + fclose(file); + exit(1); + } + + fseek(file, BLOCK_OFFSET(inode->i_block[0]), SEEK_SET); /* posiciona ponteiro da imagem do sistema */ + fread(block, BLOCK_SIZE, 1, file); /* lê bloco do disco */ + + entry = (struct ext2_dir_entry_2 *) block; /* primeira entrada no diretório */ + + int mode = inode->i_mode & 0x4000; /* atribui formato e acessos à variável */ + + while((size < inode->i_size) && entry->inode) { + if(mode == 16384){ /* verifica permissão */ + char file_name[EXT2_NAME_LEN+1]; + memcpy(file_name, entry->name, entry->name_len); + file_name[entry->name_len] = 0; /* anexa caractere nulo ao nome do arquivo */ + + printf("%10u %s\n", entry->inode, file_name); /* exibe número do inode e nome do arquivo */ + entry = (void*) entry + entry->rec_len; + size += entry->rec_len; /* atualiza tamanho */ + } + } + + free(block); /* libera memória alocada*/ +} + +char* convertNumToUnixTime(uint32_t time){ + time_t t = time; + struct tm ts; + char* buf = (char*) calloc(80, sizeof(char)); /* aloca memŕia para o buffer */ + ts = *localtime(&t); /* converte para formato UNIX */ + int year = 2022; + sprintf(buf, "%d/%d/%d %d:%d", ts.tm_mday, ts.tm_mon, year, ts.tm_hour, ts.tm_min); /* armazena no buffer */ + return buf; /* retorna o buffer com os dados */ + free(buf); /* desaloca */ } \ No newline at end of file diff --git a/utils/utils.h b/utils/utils.h index 9c1e887..556bc44 100644 --- a/utils/utils.h +++ b/utils/utils.h @@ -1,34 +1,211 @@ +/** + * @file utils.h + * @author Iago Ortega Carmona + * @author Thiago Griani Quinto + * @author Reginaldo Gregorio de Souza Neto + * @brief arquivo de declaração de funções recorrentes na implementação + * @version 0.1 + * @date 2022-12-16 + * + * + */ + #pragma once #include #include #include #include +#include +#include #include "../EXT2/ext2.h" +#include "../ListDirEntry/listDirEntry.h" +#include "../StackDirectory/stackDirectory.h" -#define BASE_OFFSET 1024 /* location of the super-block in the first group */ -#define GROUP_COUNT 8 +#define BASE_OFFSET 1024 /* localização do super bloco no primeiro grupo */ +#define GROUP_COUNT 8 /* contador de grupos */ #define BLOCK_SIZE 1024 #define BLOCK_OFFSET(block) (BASE_OFFSET + (block-1)*BASE_OFFSET) -// COLORS +/* cores */ #define BLUE(string) "\x1b[34m" string "\x1b[0m" #define RED(string) "\x1b[31m" string "\x1b[0m" #define GREEN(string) "\x1B[32m" string "\x1b[0m" #define YELLOW(string) "\x1B[33m" string "\x1b[0m" #define CYAN(string) "\x1B[36m" string "\x1b[0m" +/** + * @brief lê o superbloco do arquivo + * + * @param file o ponteiro de arquivo da onde será lido + * @param super a estrutura do superbloco onde estão armazenada as informações do sistema + */ void read_super_block(FILE* file, struct ext2_super_block* super); + + + +/** + * @brief lề as informações presentes na Descritor de Grupo + * + * @param file imagem do sistema de arquivos + * @param super a estrutura de superbloco + * @param gdesc array de descritores de grupo + */ void read_group_descriptors(FILE* file, struct ext2_super_block* super, struct ext2_group_desc* gdesc); + + + +/** + * @brief lê as informações presentes na estrutura de inode + * + * @param file imagem do sistema de arquivos + * @param inode_no o número do inode + * @param gdesc descritor de grupo do inode + * @param inode estrutura do inode que será lido + * @param super estrutura do superbloco + */ void read_inode(FILE* file, int inode_no, struct ext2_group_desc* gdesc, struct ext2_inode* inode, struct ext2_super_block* super); + + + +/** + * @brief tokenize a string passada como parâmetro em um array de strings + * + * @param commands ponteiro para um vetor de ponteiros de string + * @param arg a string que será tokenizada + * @param amountOfCommands a quantidade de comandaos a serem armazenados no array + * @return int a quantidade de caracteres + */ int tokenize_array_of_commands(char ***commands, char *arg, int *amountOfCommands); + + + + +/** + * @brief libera o vetor de de string + * + * @param commands o vetor de string que será liberado + * @param amountOfCommands a quantidade de comando no vetor + */ void destroy_array_of_commands(char **commands, int amountOfCommands); -void print_super_block(struct ext2_super_block super, unsigned int block_size); + + + + +/** + * @brief função que irá exibir as informações armazenadas na estrutura do superbloco + * + * @param super estrutura na qual as informações estão guardadas + * @param block_size tamnho do bloco + */ +void print_super_block(struct ext2_super_block* super, unsigned int block_size); + + + +/** + * @brief função que irá exibir as informações armazenadas na estrutura do Descritor de Grupo de Blocos + * + * @param gdesc estrutura na qual as informações estão guardadas + * @param i número do desritor do grupo de blocos + */ void print_group_descriptor(struct ext2_group_desc gdesc, int i); -void print_inode(struct ext2_inode inode); + + + +/** + * @brief função que irá exibir as informações armazenadas no inode + * + * @param inode estrutura na qual as informações estão guardadas + */ +void print_inode(struct ext2_inode* inode); + + + +/** + * @brief função que calcula o número de grupo de dado inode + * + * @param super estrutura de superbloco + * @param inode_no número do inode + * @return int - número de grupo do inode + */ int get_inode_group(struct ext2_super_block* super, int inode_no); + + + + +/** + * @brief função que calcula o número de inodes por bloco + * + * @param super estrura do superbloco que contém as informações necessárias + * @return int - número de inodes por bloco + */ int get_inodes_per_block(struct ext2_super_block* super); + + + +/** + * @brief função que calcula a quantidade de grupos no bloco + * + * @param super estrura do superbloco que contém as informações necessárias + * @return int - número de grupos no bloco + */ int get_amount_groups_in_block(struct ext2_super_block* super); + + + +/** + * @brief retorna o número de inodes da tabela de inodes + * + * @param super estrutura que contém as informações necessárias para a função + * @return int - número de inodes da tabela de inodes + */ int get_amount_inodes_in_itable(struct ext2_super_block* super); -int get_offset_of_inode_in_itable(struct ext2_super_block* super, struct ext2_group_desc* gdesc, int inode_no); \ No newline at end of file + + + +/** + * @brief retorna o offset de um inode da tabela de inode + * + * @param super estrutura do superbloco + * @param gdesc estrutura do Descritor do Grupo de Blocos + * @param inode_no número do inode + * @return int - offset de um inode da tabela de inode + */ +int get_offset_of_inode_in_itable(struct ext2_super_block* super, struct ext2_group_desc* gdesc, int inode_no); + + + +/** + * @brief função que procura o arquivo com o nome passado como parâmetro + * + * @param file imagem do sistema + * @param inode + * @param group Descritor de Grupo de Blocos + * @param nomeArquivo + * @return uint32_t + */ +uint32_t read_dir(FILE* file, struct ext2_inode *inode, struct ext2_group_desc *group, char* nomeArquivo); + + + + +/** + * @brief lÊ todos os diretório do bloco + * + * @param file imagem do sistema + * @param inode + * @param group Descritor de Grupo de Blocos + */ +void read_all_root_dirs(FILE* file, struct ext2_inode *inode, struct ext2_group_desc *group); + + + + +/** + * @brief converte número para o tempo UNIX + * + * @param time número que será convertido + * @return char* ponteiro para o vetor de string contendo a hora formatada + */ +char* convertNumToUnixTime(uint32_t time); \ No newline at end of file