Compare commits

..

No commits in common. "main" and "1.7.2" have entirely different histories.
main ... 1.7.2

5 changed files with 10 additions and 71 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.8..3.22) cmake_minimum_required(VERSION 3.8..3.22)
project(minitar LANGUAGES C VERSION 1.7.6) project(minitar LANGUAGES C VERSION 1.7.2)
option(MINITAR_IGNORE_UNSUPPORTED_TYPES "Skip past entries that have unsupported types instead of panicking (deprecated)" OFF) option(MINITAR_IGNORE_UNSUPPORTED_TYPES "Skip past entries that have unsupported types instead of panicking (deprecated)" OFF)

View File

@ -43,7 +43,7 @@ See [examples](examples/) for more examples using minitar.
## Project structure ## Project structure
The user-facing API (functions defined in `minitar.h` and documented in [API.md](docs/API.md)) is implemented in `src/tar.c`. Utility and internally-used functions live in `src/util.c`. The user-facing API (functions defined in `minitar.h` and documented in this README) is implemented in `src/tar.c`. Utility and internally-used functions live in `src/util.c`.
## Documentation ## Documentation
@ -75,4 +75,4 @@ pub extern "C" fn minitar_handle_panic(message: *const u8) -> !
## License ## License
`minitar` is free and open-source software under the [BSD-2-Clause](LICENSE) license. `minitar` is free and open-source software under the [BSD-2-Clause](LICENSE) license.

View File

@ -84,7 +84,7 @@ This function can be called as many times as desired, and at any given point in
This function returns the number of bytes read, or 0 on error. 0 might also be a successful return value (if `max` is 0 or the entry's size is 0, for example), which means `errno` should be checked to see if 0 means error or simply 0 bytes read. This function returns the number of bytes read, or 0 on error. 0 might also be a successful return value (if `max` is 0 or the entry's size is 0, for example), which means `errno` should be checked to see if 0 means error or simply 0 bytes read.
`minitar_read_contents()` will never read more than `metadata.size`, regardless of the value in `max`. (so, if `max == SIZE_MAX`, `minitar_read_contents()` will always read `metadata.size` bytes). `minitar_read_contents()` only reads up to `metadata.size`, regardless of the value in `max`.
The contents are not null-terminated. If you want null-termination (keep in mind the contents might not be ASCII and might contain null bytes before the end), just do `buf[nread] = 0;`. In that case, the value of `max` should be one less than the size of the buffer, to make sure the zero byte is not written past the end of `buf` if `max` bytes are read. The contents are not null-terminated. If you want null-termination (keep in mind the contents might not be ASCII and might contain null bytes before the end), just do `buf[nread] = 0;`. In that case, the value of `max` should be one less than the size of the buffer, to make sure the zero byte is not written past the end of `buf` if `max` bytes are read.

View File

@ -47,7 +47,6 @@ int main(int argc, char** argv)
if (!buf) if (!buf)
{ {
perror("malloc"); perror("malloc");
fclose(fp);
exit_status = 1; exit_status = 1;
break; break;
} }
@ -55,7 +54,8 @@ int main(int argc, char** argv)
if (ferror(fp)) if (ferror(fp))
{ {
perror("fread"); perror("fread");
goto err; exit_status = 1;
break;
} }
struct stat st; struct stat st;
@ -63,21 +63,21 @@ int main(int argc, char** argv)
if (rc < 0) if (rc < 0)
{ {
perror("fstat"); perror("fstat");
goto err; exit_status = 1;
break;
} }
struct minitar_entry_metadata metadata; struct minitar_entry_metadata metadata;
strncpy(metadata.path, argv[arg], sizeof(metadata.path)); strncpy(metadata.path, argv[arg], sizeof(metadata.path));
metadata.uid = st.st_uid; metadata.uid = st.st_uid;
metadata.gid = st.st_gid; metadata.gid = st.st_gid;
metadata.mtime = st.st_mtime; metadata.mtime = st.st_mtim.tv_sec;
metadata.size = length; metadata.size = length;
metadata.type = MTAR_REGULAR; metadata.type = MTAR_REGULAR;
metadata.mode = st.st_mode & ~S_IFMT; metadata.mode = st.st_mode & ~S_IFMT;
rc = minitar_write_file_entry(&mp, &metadata, buf); rc = minitar_write_file_entry(&mp, &metadata, buf);
free(buf); free(buf);
fclose(fp);
if (rc != 0) if (rc != 0)
{ {
@ -87,13 +87,6 @@ int main(int argc, char** argv)
} }
arg++; arg++;
continue;
err:
free(buf);
fclose(fp);
exit_status = 1;
break;
} }
minitar_close_w(&mp); minitar_close_w(&mp);
return exit_status; return exit_status;

View File

@ -9,7 +9,6 @@
#define _XOPEN_SOURCE 700 #define _XOPEN_SOURCE 700
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <libgen.h>
#include <minitar.h> #include <minitar.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -18,37 +17,8 @@
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <unistd.h> #include <unistd.h>
static int create_parent_recursively(const char* path)
{
char* path_copy = strdup(path);
if (!path_copy) return -1;
char* parent = dirname(path_copy);
create:
if (mkdir(parent, 0755) < 0)
{
if (errno == ENOENT)
{
create_parent_recursively(parent);
goto create;
}
if (errno == EEXIST) goto success;
free(path_copy);
return -1;
}
success:
free(path_copy);
return 0;
}
static int untar_file(const struct minitar_entry* entry, const void* buf) static int untar_file(const struct minitar_entry* entry, const void* buf)
{ {
if (create_parent_recursively(entry->metadata.path) < 0) return 1;
int fd = open(entry->metadata.path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0644); int fd = open(entry->metadata.path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0644);
if (fd < 0) return 1; if (fd < 0) return 1;
@ -61,8 +31,6 @@ static int untar_file(const struct minitar_entry* entry, const void* buf)
static int untar_directory(const struct minitar_entry* entry) static int untar_directory(const struct minitar_entry* entry)
{ {
if (create_parent_recursively(entry->metadata.path) < 0) return 1;
if (mkdir(entry->metadata.path, entry->metadata.mode) < 0) return 1; if (mkdir(entry->metadata.path, entry->metadata.mode) < 0) return 1;
return 0; return 0;
@ -88,7 +56,6 @@ int main(int argc, char** argv)
{ {
if (entry.metadata.type == MTAR_DIRECTORY) if (entry.metadata.type == MTAR_DIRECTORY)
{ {
if (!strcmp(entry.metadata.name, ".") || !strcmp(entry.metadata.name, "..")) continue;
int status = untar_directory(&entry); int status = untar_directory(&entry);
if (status != 0) if (status != 0)
{ {
@ -126,13 +93,10 @@ int main(int argc, char** argv)
} }
else if (entry.metadata.type == MTAR_SYMLINK) else if (entry.metadata.type == MTAR_SYMLINK)
{ {
if (create_parent_recursively(entry.metadata.path) < 0) goto symlink_err;
int status = symlink(entry.metadata.link, entry.metadata.path); int status = symlink(entry.metadata.link, entry.metadata.path);
if (status != 0) if (status != 0)
{ {
symlink_err:
fprintf(stderr, "Failed to create symlink %s: %s\n", entry.metadata.path, strerror(errno)); fprintf(stderr, "Failed to create symlink %s: %s\n", entry.metadata.path, strerror(errno));
exit_status = 1; exit_status = 1;
break; break;
@ -142,13 +106,10 @@ int main(int argc, char** argv)
} }
else if (entry.metadata.type == MTAR_HARDLINK) else if (entry.metadata.type == MTAR_HARDLINK)
{ {
if (create_parent_recursively(entry.metadata.path) < 0) goto hardlink_err;
int status = link(entry.metadata.link, entry.metadata.path); int status = link(entry.metadata.link, entry.metadata.path);
if (status != 0) if (status != 0)
{ {
hardlink_err:
fprintf(stderr, "Failed to create hard link %s: %s\n", entry.metadata.path, strerror(errno)); fprintf(stderr, "Failed to create hard link %s: %s\n", entry.metadata.path, strerror(errno));
exit_status = 1; exit_status = 1;
break; break;
@ -158,57 +119,42 @@ int main(int argc, char** argv)
} }
else if (entry.metadata.type == MTAR_FIFO) else if (entry.metadata.type == MTAR_FIFO)
{ {
#ifndef __luna__
if (create_parent_recursively(entry.metadata.path) < 0) goto fifo_err;
int status = mknod(entry.metadata.path, entry.metadata.mode | S_IFIFO, 0); int status = mknod(entry.metadata.path, entry.metadata.mode | S_IFIFO, 0);
if (status != 0) if (status != 0)
{ {
fifo_err:
fprintf(stderr, "Failed to create FIFO %s: %s\n", entry.metadata.path, strerror(errno)); fprintf(stderr, "Failed to create FIFO %s: %s\n", entry.metadata.path, strerror(errno));
exit_status = 1; exit_status = 1;
break; break;
} }
#endif
printf("fifo %s\n", entry.metadata.path); printf("fifo %s\n", entry.metadata.path);
} }
else if (entry.metadata.type == MTAR_BLKDEV) else if (entry.metadata.type == MTAR_BLKDEV)
{ {
#ifndef __luna__
if (create_parent_recursively(entry.metadata.path) < 0) goto blkdev_err;
int status = mknod(entry.metadata.path, entry.metadata.mode | S_IFBLK, int status = mknod(entry.metadata.path, entry.metadata.mode | S_IFBLK,
makedev(entry.metadata.devmajor, entry.metadata.devminor)); makedev(entry.metadata.devmajor, entry.metadata.devminor));
if (status != 0) if (status != 0)
{ {
blkdev_err:
fprintf(stderr, "Failed to create block device %s: %s\n", entry.metadata.path, strerror(errno)); fprintf(stderr, "Failed to create block device %s: %s\n", entry.metadata.path, strerror(errno));
exit_status = 1; exit_status = 1;
break; break;
} }
#endif
printf("blkdev %s (%u:%u)\n", entry.metadata.path, entry.metadata.devmajor, entry.metadata.devminor); printf("blkdev %s (%u:%u)\n", entry.metadata.path, entry.metadata.devmajor, entry.metadata.devminor);
} }
else if (entry.metadata.type == MTAR_CHRDEV) else if (entry.metadata.type == MTAR_CHRDEV)
{ {
#ifndef __luna__
if (create_parent_recursively(entry.metadata.path) < 0) goto chrdev_err;
int status = mknod(entry.metadata.path, entry.metadata.mode | S_IFCHR, int status = mknod(entry.metadata.path, entry.metadata.mode | S_IFCHR,
makedev(entry.metadata.devmajor, entry.metadata.devminor)); makedev(entry.metadata.devmajor, entry.metadata.devminor));
if (status != 0) if (status != 0)
{ {
chrdev_err:
fprintf(stderr, "Failed to create character device %s: %s\n", entry.metadata.path, strerror(errno)); fprintf(stderr, "Failed to create character device %s: %s\n", entry.metadata.path, strerror(errno));
exit_status = 1; exit_status = 1;
break; break;
} }
#endif
printf("chrdev %s (%u:%u)\n", entry.metadata.path, entry.metadata.devmajor, entry.metadata.devminor); printf("chrdev %s (%u:%u)\n", entry.metadata.path, entry.metadata.devmajor, entry.metadata.devminor);
} }
@ -224,4 +170,4 @@ int main(int argc, char** argv)
} while (1); } while (1);
minitar_close(&mp); minitar_close(&mp);
return exit_status; return exit_status;
} }