Compare commits

...

8 Commits
1.7.3 ... main

Author SHA1 Message Date
1ce643b0c8
chore: bump patch version 2023-12-12 23:29:23 +01:00
ae7bf076dc
fix: Avoid leaking all kinds of stuff in examples/pack
Apart from potentionally leaking malloced memory on error,
which isn't too bad since we immediately exit afterwards,
we were leaving all opened files dangling, as fclose() was never called.
2023-12-12 23:27:05 +01:00
73c4dce573
fix: Functions implemented in tar.c are no longer implemented in the README 2023-06-18 21:09:35 +02:00
7ef1c80fb6
chore: bump patch version 2023-06-18 20:53:56 +02:00
6b1b8fef55
fix: Don't create . or .. in the untar example 2023-06-17 12:05:13 +02:00
cd0c5df5f5
chore: bump patch version 2023-05-27 20:02:46 +02:00
1644ab59eb
fix: Add support for my own OS to examples
Luna doesn't support FIFOs, and special device files are
automatically created by the kernel, so there is no mknod().
2023-05-27 19:58:23 +02:00
f12f58bacf
fix: Make the untar example create parent directories for all entry types 2023-03-08 17:05:10 +01:00
4 changed files with 40 additions and 10 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.3) project(minitar LANGUAGES C VERSION 1.7.6)
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 this README) 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 [API.md](docs/API.md)) is implemented in `src/tar.c`. Utility and internally-used functions live in `src/util.c`.
## Documentation ## Documentation

View File

@ -47,6 +47,7 @@ int main(int argc, char** argv)
if (!buf) if (!buf)
{ {
perror("malloc"); perror("malloc");
fclose(fp);
exit_status = 1; exit_status = 1;
break; break;
} }
@ -54,8 +55,7 @@ int main(int argc, char** argv)
if (ferror(fp)) if (ferror(fp))
{ {
perror("fread"); perror("fread");
exit_status = 1; goto err;
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");
exit_status = 1; goto err;
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_mtim.tv_sec; metadata.mtime = st.st_mtime;
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,6 +87,13 @@ 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

@ -18,7 +18,6 @@
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <unistd.h> #include <unistd.h>
// NOTE: This should be done for all entries, not just regular files
static int create_parent_recursively(const char* path) static int create_parent_recursively(const char* path)
{ {
char* path_copy = strdup(path); char* path_copy = strdup(path);
@ -62,6 +61,8 @@ 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;
@ -87,6 +88,7 @@ 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)
{ {
@ -124,10 +126,13 @@ 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;
@ -137,10 +142,13 @@ 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;
@ -150,42 +158,57 @@ 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);
} }