tarfilter.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * This file is in the public domain.
  3. *
  4. * Feel free to use it as you wish.
  5. */
  6. /*
  7. * This example program reads an archive from stdin (which can be in
  8. * any format recognized by libarchive) and writes certain entries to
  9. * an uncompressed ustar archive on stdout. This is a template for
  10. * many kinds of archive manipulation: converting formats, resetting
  11. * ownership, inserting entries, removing entries, etc.
  12. *
  13. * To compile:
  14. * gcc -Wall -o tarfilter tarfilter.c -larchive -lz -lbz2
  15. */
  16. #include <sys/stat.h>
  17. #include <archive.h>
  18. #include <archive_entry.h>
  19. #include <stdarg.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. static void
  23. die(char *fmt, ...)
  24. {
  25. va_list ap;
  26. va_start(ap, fmt);
  27. vfprintf(stderr, fmt, ap);
  28. va_end(ap);
  29. fprintf(stderr, "\n");
  30. exit(1);
  31. }
  32. int
  33. main(int argc, char **argv)
  34. {
  35. char buff[8192];
  36. ssize_t len;
  37. int r;
  38. mode_t m;
  39. struct archive *ina;
  40. struct archive *outa;
  41. struct archive_entry *entry;
  42. /* Read an archive from stdin, with automatic format detection. */
  43. ina = archive_read_new();
  44. if (ina == NULL)
  45. die("Couldn't create archive reader.");
  46. if (archive_read_support_compression_all(ina) != ARCHIVE_OK)
  47. die("Couldn't enable decompression");
  48. if (archive_read_support_format_all(ina) != ARCHIVE_OK)
  49. die("Couldn't enable read formats");
  50. if (archive_read_open_fd(ina, 0, 10240) != ARCHIVE_OK)
  51. die("Couldn't open input archive");
  52. /* Write an uncompressed ustar archive to stdout. */
  53. outa = archive_write_new();
  54. if (outa == NULL)
  55. die("Couldn't create archive writer.");
  56. if (archive_write_set_compression_none(outa) != ARCHIVE_OK)
  57. die("Couldn't enable compression");
  58. if (archive_write_set_format_ustar(outa) != ARCHIVE_OK)
  59. die("Couldn't set output format");
  60. if (archive_write_open_fd(outa, 1) != ARCHIVE_OK)
  61. die("Couldn't open output archive");
  62. /* Examine each entry in the input archive. */
  63. while ((r = archive_read_next_header(ina, &entry)) == ARCHIVE_OK) {
  64. fprintf(stderr, "%s: ", archive_entry_pathname(entry));
  65. /* Skip anything that isn't a regular file. */
  66. if (!S_ISREG(archive_entry_mode(entry))) {
  67. fprintf(stderr, "skipped\n");
  68. continue;
  69. }
  70. /* Make everything owned by root/wheel. */
  71. archive_entry_set_uid(entry, 0);
  72. archive_entry_set_uname(entry, "root");
  73. archive_entry_set_gid(entry, 0);
  74. archive_entry_set_gname(entry, "wheel");
  75. /* Make everything permission 0744, strip SUID, etc. */
  76. m = archive_entry_mode(entry);
  77. archive_entry_set_mode(entry, (m & ~07777) | 0744);
  78. /* Copy input entries to output archive. */
  79. if (archive_write_header(outa, entry) != ARCHIVE_OK)
  80. die("Error writing output archive");
  81. if (archive_entry_size(entry) > 0) {
  82. len = archive_read_data(ina, buff, sizeof(buff));
  83. while (len > 0) {
  84. if (archive_write_data(outa, buff, len) != len)
  85. die("Error writing output archive");
  86. len = archive_read_data(ina, buff, sizeof(buff));
  87. }
  88. if (len < 0)
  89. die("Error reading input archive");
  90. }
  91. fprintf(stderr, "copied\n");
  92. }
  93. if (r != ARCHIVE_EOF)
  94. die("Error reading archive");
  95. /* Close the archives. */
  96. if (archive_read_finish(ina) != ARCHIVE_OK)
  97. die("Error closing input archive");
  98. if (archive_write_finish(outa) != ARCHIVE_OK)
  99. die("Error closing output archive");
  100. return (0);
  101. }