aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/archive.c52
-rw-r--r--src/args.c1
-rw-r--r--src/fs.c11
-rw-r--r--src/utils.c35
4 files changed, 89 insertions, 10 deletions
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;
}
diff --git a/src/args.c b/src/args.c
index 1600e0e..9403145 100644
--- a/src/args.c
+++ b/src/args.c
@@ -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)
diff --git a/src/fs.c b/src/fs.c
index 24de763..df201b4 100644
--- a/src/fs.c
+++ b/src/fs.c
@@ -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
+ );
+}