diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-06-22 19:48:39 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-06-22 19:48:39 +0200 |
| commit | d99f14c2a908b9db8d24180c9681009a4d1c0207 (patch) | |
| tree | 935d334b242e38f70ef1e503446a35f0b66e104c | |
| parent | 88ab5a5273e13066ce3f496a690f10d20a278bb4 (diff) | |
| download | tar-d99f14c2a908b9db8d24180c9681009a4d1c0207.tar.gz tar-d99f14c2a908b9db8d24180c9681009a4d1c0207.tar.bz2 tar-d99f14c2a908b9db8d24180c9681009a4d1c0207.zip | |
Added list option and verbose mode
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | inc/tar.h | 13 | ||||
| -rw-r--r-- | src/archive.c | 52 | ||||
| -rw-r--r-- | src/args.c | 1 | ||||
| -rw-r--r-- | src/fs.c | 11 | ||||
| -rw-r--r-- | src/utils.c | 35 |
6 files changed, 100 insertions, 16 deletions
@@ -6,8 +6,8 @@ Shitty clone of the `tar` program made for educational purposes. - [x] `x` Extracting archive - [ ] `d` Difference between file system and archive -- [ ] `t` List archive -- [ ] `v` Verbose mode +- [x] `t` List archive +- [x] `v` Verbose mode - [ ] `A` Concatenate 2 archives together - [ ] `r` Add files to archive - [ ] `u` Update file in archive @@ -27,6 +27,7 @@ # include <grp.h> # include <pwd.h> +# include <time.h> # include <limits.h> # ifdef __linux__ @@ -91,13 +92,13 @@ int header_parse(char record[RECORD_SIZE], struct stat *statbuf, t_header *hea // fs.c int file_content_write(int fd, int file_fd, struct stat *statbuf); -int file_write(int fd, char file_name[PATH_MAX]); -int directory_write(int fd, char dir_name[PATH_MAX]); +int file_write(int fd, char file_name[PATH_MAX], bool verbose); +int directory_write(int fd, char dir_name[PATH_MAX], bool verbose); // archive.c int archive_dispatch_action(int archive_fd, t_args *args); -int archive_create(int archive_fd, char **files); -int archive_extract(int archive_fd); +int archive_create(int archive_fd, char **files, bool verbose); +int archive_extract(int archive_fd, bool verbose); int archive_get_fd(t_args *args); // record.c @@ -109,4 +110,8 @@ bool record_is_blank(char record[RECORD_SIZE]); // args.c bool args_parse(int argc, char **argv, t_args *args); +// utils.c +void put_file_name(char *file_name); +void put_file_verbose(t_header *header, struct stat *statbuf); + #endif // TAR_H diff --git a/src/archive.c b/src/archive.c index 48fa55d..111d1c0 100644 --- a/src/archive.c +++ b/src/archive.c @@ -1,6 +1,6 @@ #include "tar.h" -int archive_create(int archive_fd, char **files) +int archive_create(int archive_fd, char **files, bool verbose) { char file_name[PATH_MAX]; struct stat root_statbuf; @@ -9,7 +9,7 @@ int archive_create(int archive_fd, char **files) { bzero(file_name, PATH_MAX); strcpy(file_name, *files); - file_write(archive_fd, file_name); + file_write(archive_fd, file_name, verbose); } if (stat("/", &root_statbuf) == -1) { @@ -21,7 +21,7 @@ int archive_create(int archive_fd, char **files) return 0; } -int archive_extract(int archive_fd) +int archive_extract(int archive_fd, bool verbose) { char record[RECORD_SIZE]; t_header header; @@ -44,6 +44,8 @@ int archive_extract(int archive_fd) if (header_parse(record, &statbuf, &header) == -1) return -1; + if (verbose) + put_file_name(header.file_name); switch (header.file_type[0]) { case '5': @@ -77,6 +79,42 @@ int archive_extract(int archive_fd) return 0; } +int archive_list(int archive_fd, bool verbose) +{ + char record[RECORD_SIZE]; + struct stat statbuf; + t_header header; + + while (true) + { + if (record_read(archive_fd, record) == -1) + return -1; + if (record_is_blank(record)) + { + if (record_read(archive_fd, record) == -1) + return -1; + if (record_is_blank(record)) + break; + else + return -1; + } + if (header_parse(record, &statbuf, &header) == -1) + return -1; + if (!verbose) + put_file_name(header.file_name); + else + put_file_verbose(&header, &statbuf); + + if (header.file_type[0] == '0' && + lseek(archive_fd, statbuf.st_size + (RECORD_SIZE - statbuf.st_size % RECORD_SIZE), SEEK_CUR) == -1) + { + perror(NULL); + return -1; + } + } + return 0; +} + int archive_get_fd(t_args *args) { int fd; @@ -101,12 +139,16 @@ int archive_get_fd(t_args *args) int archive_dispatch_action(int archive_fd, t_args *args) { + bool verbose = args->flags & FLAG_VERBOSE; + switch (args->action) { case ACTION_CREATE: - return archive_create(archive_fd, args->files); + return archive_create(archive_fd, args->files, verbose); case ACTION_EXTRACT: - return archive_extract(archive_fd); + return archive_extract(archive_fd, verbose); + case ACTION_LIST: + return archive_list(archive_fd, verbose); default: return -1; } @@ -5,6 +5,7 @@ bool args_parse(int argc, char **argv, t_args *args) int opt; int action_counter = 0; + args->flags = 0; args->archive_name = NULL; args->files = NULL; while ((opt = getopt(argc, argv, "Acdtruxvf:")) != -1) @@ -23,12 +23,13 @@ int file_content_write(int fd, int file_fd, struct stat *statbuf) return (ret); } -int file_write(int fd, char file_name[PATH_MAX]) +int file_write(int fd, char file_name[PATH_MAX], bool verbose) { int file_fd; struct stat statbuf; - /* fprintf(stderr, "|%s|\n", file_name); */ + if (verbose) + put_file_name(file_name); if (stat(file_name, &statbuf) == -1) { perror("file_write stat"); @@ -40,7 +41,7 @@ int file_write(int fd, char file_name[PATH_MAX]) switch (statbuf.st_mode & S_IFMT) { case S_IFDIR: - return directory_write(fd, file_name); + return directory_write(fd, file_name, verbose); default: if ((file_fd = open(file_name, O_RDONLY)) == -1) { @@ -52,7 +53,7 @@ int file_write(int fd, char file_name[PATH_MAX]) return (0); } -int directory_write(int fd, char dir_name[PATH_MAX]) +int directory_write(int fd, char dir_name[PATH_MAX], bool verbose) { DIR *dir; struct dirent *entry; @@ -72,7 +73,7 @@ int directory_write(int fd, char dir_name[PATH_MAX]) strcmp(entry->d_name, "..") == 0) continue; strcat(dir_name, entry->d_name); - if (file_write(fd, dir_name) == -1) + if (file_write(fd, dir_name, verbose) == -1) { closedir(dir); return -1; diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..5d3608f --- /dev/null +++ b/src/utils.c @@ -0,0 +1,35 @@ +#include "tar.h" + +void put_file_name(char *file_name) +{ + fputs(file_name, stderr); + fputc('\n', stderr); +} + +void put_file_verbose(t_header *header, struct stat *statbuf) +{ + char *time_str; + char *new_line_ptr; + + time_str = ctime(&statbuf->st_mtime); + if ((new_line_ptr = strchr(time_str, '\n')) != NULL) + *new_line_ptr = '\0'; + printf( + "%c%c%c%c%c%c%c%c%c%c %s/%s %6lu %s %s\n", + header->file_type[0] == '0' ? '-' : 'd', + statbuf->st_mode & S_IRUSR ? 'r' : '-', + statbuf->st_mode & S_IWUSR ? 'w' : '-', + statbuf->st_mode & S_IXUSR ? 'x' : '-', + statbuf->st_mode & S_IRGRP ? 'r' : '-', + statbuf->st_mode & S_IWGRP ? 'w' : '-', + statbuf->st_mode & S_IXGRP ? 'x' : '-', + statbuf->st_mode & S_IROTH ? 'r' : '-', + statbuf->st_mode & S_IWOTH ? 'w' : '-', + statbuf->st_mode & S_IXOTH ? 'x' : '-', + header->user_name, + header->group_name, + statbuf->st_size, + time_str, + header->file_name + ); +} |
