aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-06-22 20:25:18 +0200
committerCharles <sircharlesaze@gmail.com>2020-06-22 20:25:18 +0200
commit8f3aa1e98c2dc8e7cd96c4bf3efe8d0603651c86 (patch)
treedb7bfb4bf44d63869430036c48844d3da5809d17
parentd99f14c2a908b9db8d24180c9681009a4d1c0207 (diff)
downloadtar-master.tar.gz
tar-master.tar.bz2
tar-master.zip
Added diff optionHEADmaster
-rw-r--r--README.md6
-rw-r--r--src/archive.c55
2 files changed, 52 insertions, 9 deletions
diff --git a/README.md b/README.md
index cb25714..3cf88fc 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Shitty clone of the `tar` program made for educational purposes.
## TODO
- [x] `x` Extracting archive
-- [ ] `d` Difference between file system and archive
+- [x] `d` Difference between file system and archive
- [x] `t` List archive
- [x] `v` Verbose mode
- [ ] `A` Concatenate 2 archives together
@@ -13,3 +13,7 @@ Shitty clone of the `tar` program made for educational purposes.
- [ ] `u` Update file in archive
- [ ] Remove `..` from member name
- [ ] Complete ustar format
+ - [ ] Device handling
+ - [ ] Soft link handling
+ - [ ] Hard link handling
+ - [ ] Filename prefix used for >100 file\_name
diff --git a/src/archive.c b/src/archive.c
index 111d1c0..9a2b992 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -79,7 +79,7 @@ int archive_extract(int archive_fd, bool verbose)
return 0;
}
-int archive_list(int archive_fd, bool verbose)
+int archive_header_iter(int archive_fd, bool verbose, int (*f)(t_header*, struct stat*, bool))
{
char record[RECORD_SIZE];
struct stat statbuf;
@@ -100,11 +100,8 @@ int archive_list(int archive_fd, bool verbose)
}
if (header_parse(record, &statbuf, &header) == -1)
return -1;
- if (!verbose)
- put_file_name(header.file_name);
- else
- put_file_verbose(&header, &statbuf);
-
+ if (f(&header, &statbuf, verbose) == -1)
+ return -1;
if (header.file_type[0] == '0' &&
lseek(archive_fd, statbuf.st_size + (RECORD_SIZE - statbuf.st_size % RECORD_SIZE), SEEK_CUR) == -1)
{
@@ -115,7 +112,47 @@ int archive_list(int archive_fd, bool verbose)
return 0;
}
-int archive_get_fd(t_args *args)
+int archive_list_func(t_header *header, struct stat *statbuf, bool verbose)
+{
+ if (!verbose)
+ put_file_name(header->file_name);
+ else
+ put_file_verbose(header, statbuf);
+ return 0;
+}
+
+int archive_list(int archive_fd, bool verbose)
+{
+ return archive_header_iter(archive_fd, verbose, archive_list_func);
+}
+
+int archive_diff_func(t_header *header, struct stat *statbuf, bool verbose)
+{
+ struct stat current_statbuf;
+
+ if (verbose)
+ put_file_name(header->file_name);
+ if (stat(header->file_name, &current_statbuf) == -1)
+ return -1;
+ if (S_ISDIR(current_statbuf.st_mode))
+ return 0;
+ if (statbuf->st_uid != current_statbuf.st_uid)
+ printf("%s: Uid differs\n", header->file_name);
+ if (statbuf->st_gid != current_statbuf.st_gid)
+ printf("%s: Gid differs\n", header->file_name);
+ if (statbuf->st_mtime != current_statbuf.st_mtime)
+ printf("%s: Mod time differs\n", header->file_name);
+ if (statbuf->st_size != current_statbuf.st_size)
+ printf("%s: Size differs\n", header->file_name);
+ return 0;
+}
+
+int archive_diff(int archive_fd, bool verbose)
+{
+ return archive_header_iter(archive_fd, verbose, archive_diff_func);
+}
+
+int archive_get_fd(t_args *args)
{
int fd;
bool is_read;
@@ -137,7 +174,7 @@ int archive_get_fd(t_args *args)
return fd;
}
-int archive_dispatch_action(int archive_fd, t_args *args)
+int archive_dispatch_action(int archive_fd, t_args *args)
{
bool verbose = args->flags & FLAG_VERBOSE;
@@ -149,6 +186,8 @@ int archive_dispatch_action(int archive_fd, t_args *args)
return archive_extract(archive_fd, verbose);
case ACTION_LIST:
return archive_list(archive_fd, verbose);
+ case ACTION_DIFF:
+ return archive_diff(archive_fd, verbose);
default:
return -1;
}