diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-06-21 18:16:47 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-06-21 18:16:47 +0200 |
| commit | 3f37f1c9bf64866de90ec418adcfe31b634231c2 (patch) | |
| tree | 79c12d6255f54ec1049b0b5863c8d6662345518e | |
| parent | 0fa3308034c7776b6c078e493f3b758f0a0bf7e6 (diff) | |
| download | tar-3f37f1c9bf64866de90ec418adcfe31b634231c2.tar.gz tar-3f37f1c9bf64866de90ec418adcfe31b634231c2.tar.bz2 tar-3f37f1c9bf64866de90ec418adcfe31b634231c2.zip | |
Added archive_write, archive_read draft
| -rw-r--r-- | README.md | 10 | ||||
| -rw-r--r-- | inc/tar.h | 26 | ||||
| -rw-r--r-- | src/archive.c | 73 | ||||
| -rw-r--r-- | src/main.c | 39 | ||||
| -rw-r--r-- | src/utils.c (renamed from src/header.c) | 44 |
5 files changed, 156 insertions, 36 deletions
@@ -1,3 +1,13 @@ # tar Shitty clone of the `tar` program made for educational purposes. + +## TODO + +- [ ] `x` Extracting archive +- [ ] `d` Difference between file system and archive +- [ ] `t` List archive +- [ ] `v` Verbose mode +- [ ] `A` Concatenate 2 archives together +- [ ] `r` Add files to archive +- [ ] `u` Update file in archive @@ -45,7 +45,7 @@ typedef struct char user_id[8]; char group_id[8]; char file_size[12]; - char last_time[12]; + char last_time[12]; // utime char checksum[8]; char file_type[1]; char link_file_name[100]; @@ -58,13 +58,25 @@ typedef struct char file_name_prefix[155]; } t_header; -// header.c -int record_write(int fd, char *s, size_t size); -int header_write(int fd, char *file_name, struct stat *statbuf); +typedef enum +{ + FLAG_CREATE = 1 << 0, + FLAG_VERBOSE = 1 << 0, + FLAG_LIST = 1 << 0, +} t_flags; + +// utils.c +int record_write(int fd, char *s, size_t size); +int record_write_blank(int fd, size_t count); +int header_write(int fd, char *file_name, struct stat *statbuf); // 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_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]); + +// archive.c +int archive_write(char *archive_file_name, char **files); +int archive_read(char *archive_file_name); #endif // TAR_H diff --git a/src/archive.c b/src/archive.c new file mode 100644 index 0000000..11457d6 --- /dev/null +++ b/src/archive.c @@ -0,0 +1,73 @@ +#include "tar.h" + +int archive_write(char *archive_file_name, char **files) +{ + int fd; + char file_name[PATH_MAX]; + struct stat root_statbuf; + + if (archive_file_name == NULL) + fd = STDOUT_FILENO; + else + { + fd = open(archive_file_name, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) + { + perror("achive_write"); + return -1; + } + } + for (; *files != NULL; files++) + { + bzero(file_name, PATH_MAX); + strcpy(file_name, *files); + file_write(fd, file_name); + } + if (stat("/", &root_statbuf) == -1) + { + perror("achive_write"); + close(fd); + return -1; + } + if (record_write_blank(fd, 2 + (2 * root_statbuf.st_blksize) / RECORD_SIZE) == -1) + { + close(fd); + return -1; + } + if (fd != STDOUT_FILENO) + close(fd); + return 0; +} + +int archive_read(char *archive_file_name) +{ + int fd; + + if ((fd = open(archive_file_name, O_RDONLY)) == -1) + { + perror("achive_write"); + return -1; + } + + int ret; + char buf[RECORD_SIZE]; + t_header header; + int current_fd; + + while ((ret = read(fd, buf, RECORD_SIZE)) == RECORD_SIZE) + { + /* header_parse(&header, buf); */ + /* current_fd = open(header.file_name, O_WRONLY | O_CREAT | O_TRUNC, header. */ + // read content + // TODO + } + if (ret == -1) + { + perror(NULL); + return -1; + } + if (ret < RECORD_SIZE) + return -1; + close(fd); + return 0; +} @@ -6,16 +6,21 @@ int main(int argc, char **argv) { int opt; - char *output_file_name = NULL; + char *archive_file_name = NULL; + bool create; - while ((opt = getopt(argc, argv, "cvtf:")) != -1) + while ((opt = getopt(argc, argv, "Oxcvtf:")) != -1) { switch (opt) { case 'c': + create = true; + break; + case 'x': + create = false; break; case 'f': - output_file_name = optarg; + archive_file_name = optarg; break; case 'v': break; @@ -25,33 +30,15 @@ int main(int argc, char **argv) return 1; } } - int fd = -1; - if (output_file_name == NULL) - fd = STDOUT_FILENO; - else + if (create) { - fd = open(output_file_name, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) - { - perror("main"); + if (archive_write(archive_file_name, argv + optind) == -1) return 1; - } } - - /* printf("out: %s\n", output_file_name); */ - char file_name[PATH_MAX]; - char **files = argv + optind; - for (; *files != NULL; files++) + else { - /* printf("%s\n", *files); */ - bzero(file_name, PATH_MAX); - strcpy(file_name, *files); - file_write(fd, file_name); + if (archive_read(archive_file_name) == -1) + return 1; } - char buf[512] = {'\0'}; - write(fd, buf, 512); - write(fd, buf, 512); - if (fd != STDOUT_FILENO) - close(fd); return 0; } diff --git a/src/header.c b/src/utils.c index 133a895..ce56307 100644 --- a/src/header.c +++ b/src/utils.c @@ -25,6 +25,20 @@ int record_write(int fd, char *s, size_t size) return (0); } +int record_write_blank(int fd, size_t count) +{ + char buf[RECORD_SIZE] = {0}; + while (count-- > 0) + { + if (write(fd, buf, RECORD_SIZE) == -1) + { + perror(NULL); + return -1; + } + } + return 0; +} + int header_write(int fd, char *file_name, struct stat *statbuf) { t_header header; @@ -39,7 +53,12 @@ int header_write(int fd, char *file_name, struct stat *statbuf) sprintf(header.file_mode, "%07o", statbuf->st_mode & 0777); sprintf(header.user_id, "%07o", statbuf->st_uid); sprintf(header.group_id, "%07o", statbuf->st_gid); - sprintf(header.file_size, "%011lo", statbuf->st_size); + + if (S_ISDIR(statbuf->st_mode)) + sprintf(header.file_size, "%011lo", 0lu); + else + sprintf(header.file_size, "%011lo", statbuf->st_size); + sprintf(header.last_time, "%011lo", statbuf->st_mtime); memset(header.checksum, ' ', sizeof(header.checksum)); @@ -70,11 +89,30 @@ int header_write(int fd, char *file_name, struct stat *statbuf) } strncpy(header.group_name, group->gr_name, sizeof(header.group_name)); - /* getpwuid(); */ - + sum = 0; for (size_t i = 0; i < sizeof(t_header); i++) sum += ((uint8_t*)&header)[i]; sprintf(header.checksum, "%06o", sum); return record_write(fd, (char*)&header, sizeof(t_header)); } + +int header_parse(char record[RECORD_SIZE]) +{ + t_header header; + mode_t mode; + gid_t gid; + uid_t uid; + + memcpy(&header, record, sizeof(t_header)); + /* sscanf(header.file_mode, "% */ + + /* sscanf(header.file_mode, "%07o", statbuf->st_mode); */ + /* sscanf(header.user_id, "%07o", statbuf->st_uid); */ + /* sscanf(header.group_id, "%07o", statbuf->st_gid); */ + /* */ + /* sscanf(header.file_size, "%011lo", statbuf->st_size); */ + /* */ + /* sscanf(header.last_time, "%011lo", statbuf->st_mtime); */ + return 0; +} |
