|
Packit Service |
1d0348 |
/*
|
|
Packit Service |
1d0348 |
* This file is in the public domain.
|
|
Packit Service |
1d0348 |
*
|
|
Packit Service |
1d0348 |
* Feel free to use it as you wish.
|
|
Packit Service |
1d0348 |
*/
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
/*
|
|
Packit Service |
1d0348 |
* This example program reads an archive from stdin (which can be in
|
|
Packit Service |
1d0348 |
* any format recognized by libarchive) and writes certain entries to
|
|
Packit Service |
1d0348 |
* an uncompressed ustar archive on stdout. This is a template for
|
|
Packit Service |
1d0348 |
* many kinds of archive manipulation: converting formats, resetting
|
|
Packit Service |
1d0348 |
* ownership, inserting entries, removing entries, etc.
|
|
Packit Service |
1d0348 |
*
|
|
Packit Service |
1d0348 |
* To compile:
|
|
Packit Service |
1d0348 |
* gcc -Wall -o tarfilter tarfilter.c -larchive -lz -lbz2
|
|
Packit Service |
1d0348 |
*/
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
#include <sys/stat.h>
|
|
Packit Service |
1d0348 |
#include <archive.h>
|
|
Packit Service |
1d0348 |
#include <archive_entry.h>
|
|
Packit Service |
1d0348 |
#include <stdarg.h>
|
|
Packit Service |
1d0348 |
#include <stdio.h>
|
|
Packit Service |
1d0348 |
#include <stdlib.h>
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
static void
|
|
Packit Service |
1d0348 |
die(char *fmt, ...)
|
|
Packit Service |
1d0348 |
{
|
|
Packit Service |
1d0348 |
va_list ap;
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
va_start(ap, fmt);
|
|
Packit Service |
1d0348 |
vfprintf(stderr, fmt, ap);
|
|
Packit Service |
1d0348 |
va_end(ap);
|
|
Packit Service |
1d0348 |
fprintf(stderr, "\n");
|
|
Packit Service |
1d0348 |
exit(1);
|
|
Packit Service |
1d0348 |
}
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
int
|
|
Packit Service |
1d0348 |
main(int argc, char **argv)
|
|
Packit Service |
1d0348 |
{
|
|
Packit Service |
1d0348 |
char buff[8192];
|
|
Packit Service |
1d0348 |
ssize_t len;
|
|
Packit Service |
1d0348 |
int r;
|
|
Packit Service |
1d0348 |
mode_t m;
|
|
Packit Service |
1d0348 |
struct archive *ina;
|
|
Packit Service |
1d0348 |
struct archive *outa;
|
|
Packit Service |
1d0348 |
struct archive_entry *entry;
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
/* Read an archive from stdin, with automatic format detection. */
|
|
Packit Service |
1d0348 |
ina = archive_read_new();
|
|
Packit Service |
1d0348 |
if (ina == NULL)
|
|
Packit Service |
1d0348 |
die("Couldn't create archive reader.");
|
|
Packit Service |
1d0348 |
if (archive_read_support_filter_all(ina) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Couldn't enable decompression");
|
|
Packit Service |
1d0348 |
if (archive_read_support_format_all(ina) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Couldn't enable read formats");
|
|
Packit Service |
1d0348 |
if (archive_read_open_fd(ina, 0, 10240) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Couldn't open input archive");
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
/* Write an uncompressed ustar archive to stdout. */
|
|
Packit Service |
1d0348 |
outa = archive_write_new();
|
|
Packit Service |
1d0348 |
if (outa == NULL)
|
|
Packit Service |
1d0348 |
die("Couldn't create archive writer.");
|
|
Packit Service |
1d0348 |
if (archive_write_set_compression_none(outa) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Couldn't enable compression");
|
|
Packit Service |
1d0348 |
if (archive_write_set_format_ustar(outa) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Couldn't set output format");
|
|
Packit Service |
1d0348 |
if (archive_write_open_fd(outa, 1) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Couldn't open output archive");
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
/* Examine each entry in the input archive. */
|
|
Packit Service |
1d0348 |
while ((r = archive_read_next_header(ina, &entry)) == ARCHIVE_OK) {
|
|
Packit Service |
1d0348 |
fprintf(stderr, "%s: ", archive_entry_pathname(entry));
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
/* Skip anything that isn't a regular file. */
|
|
Packit Service |
1d0348 |
if (!S_ISREG(archive_entry_mode(entry))) {
|
|
Packit Service |
1d0348 |
fprintf(stderr, "skipped\n");
|
|
Packit Service |
1d0348 |
continue;
|
|
Packit Service |
1d0348 |
}
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
/* Make everything owned by root/wheel. */
|
|
Packit Service |
1d0348 |
archive_entry_set_uid(entry, 0);
|
|
Packit Service |
1d0348 |
archive_entry_set_uname(entry, "root");
|
|
Packit Service |
1d0348 |
archive_entry_set_gid(entry, 0);
|
|
Packit Service |
1d0348 |
archive_entry_set_gname(entry, "wheel");
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
/* Make everything permission 0744, strip SUID, etc. */
|
|
Packit Service |
1d0348 |
m = archive_entry_mode(entry);
|
|
Packit Service |
1d0348 |
archive_entry_set_mode(entry, (m & ~07777) | 0744);
|
|
Packit Service |
1d0348 |
|
|
Packit Service |
1d0348 |
/* Copy input entries to output archive. */
|
|
Packit Service |
1d0348 |
if (archive_write_header(outa, entry) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Error writing output archive");
|
|
Packit Service |
1d0348 |
if (archive_entry_size(entry) > 0) {
|
|
Packit Service |
1d0348 |
len = archive_read_data(ina, buff, sizeof(buff));
|
|
Packit Service |
1d0348 |
while (len > 0) {
|
|
Packit Service |
1d0348 |
if (archive_write_data(outa, buff, len) != len)
|
|
Packit Service |
1d0348 |
die("Error writing output archive");
|
|
Packit Service |
1d0348 |
len = archive_read_data(ina, buff, sizeof(buff));
|
|
Packit Service |
1d0348 |
}
|
|
Packit Service |
1d0348 |
if (len < 0)
|
|
Packit Service |
1d0348 |
die("Error reading input archive");
|
|
Packit Service |
1d0348 |
}
|
|
Packit Service |
1d0348 |
fprintf(stderr, "copied\n");
|
|
Packit Service |
1d0348 |
}
|
|
Packit Service |
1d0348 |
if (r != ARCHIVE_EOF)
|
|
Packit Service |
1d0348 |
die("Error reading archive");
|
|
Packit Service |
1d0348 |
/* Close the archives. */
|
|
Packit Service |
1d0348 |
if (archive_read_free(ina) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Error closing input archive");
|
|
Packit Service |
1d0348 |
if (archive_write_free(outa) != ARCHIVE_OK)
|
|
Packit Service |
1d0348 |
die("Error closing output archive");
|
|
Packit Service |
1d0348 |
return (0);
|
|
Packit Service |
1d0348 |
}
|