Esempio n. 1
0
void Writer::set_format_helper(struct archive *ar, int format)
{
    std::string error_msg;

    switch(format) {
        case Archive::FORMAT_AR_BSD:
            archive_write_set_format_ar_bsd(ar);
            break;
        case Archive::FORMAT_AR_SVR4:
            archive_write_set_format_ar_svr4(ar);
            break;
        case Archive::FORMAT_CPIO:
            archive_write_set_format_cpio(ar);
            break;
        case Archive::FORMAT_CPIO_NEWC:
            archive_write_set_format_cpio_newc(ar);
            break;
        case Archive::FORMAT_MTREE:
            archive_write_set_format_mtree(ar);
            break;
        case Archive::FORMAT_TAR:
        case Archive::FORMAT_TAR_PAX_RESTRICTED:
            archive_write_set_format_pax_restricted(ar);
            break;
        case Archive::FORMAT_TAR_PAX_INTERCHANGE:
            archive_write_set_format_pax(ar);
            break;
        case Archive::FORMAT_TAR_USTAR:
            archive_write_set_format_ustar(ar);
            break;
        default:
            error_msg = "unknown or unsupported archive format";
            throw Error(error_msg);
    }
}
Esempio n. 2
0
static int archive_conv_open(struct archive_conv *conv,
                             const struct repo_t *repo) {
  int r;

  /* generally, repo files are gzip compressed, but there's no guarantee of
   * this. in order to be compression-agnostic, use libarchive's reader/writer
   * methods. this also gives us an opportunity to rewrite the archive as CPIO,
   * which is marginally faster given our staunch sequential access. */

  conv->reponame = repo->name;
  stpcpy(stpcpy(conv->tmpfile, repo->diskfile), "~");

  conv->in = archive_read_new();
  conv->out = archive_write_new();

  if (conv->in == NULL || conv->out == NULL) {
    fputs("error: failed to allocate memory for archive objects\n", stderr);
    return -ENOMEM;
  }

  archive_read_support_format_tar(conv->in);
  archive_read_support_filter_all(conv->in);
  r = archive_read_open_fd(conv->in, repo->tmpfile.fd, BUFSIZ);
  if (r != ARCHIVE_OK) {
    fprintf(stderr, "error: failed to create archive reader for %s: %s\n",
            repo->name, strerror(archive_errno(conv->in)));
    r = archive_errno(conv->in);
    goto open_error;
  }

  archive_write_set_format_cpio_newc(conv->out);
  archive_write_add_filter(conv->out, repo->config->compress);
  r = archive_write_open_filename(conv->out, conv->tmpfile);
  if (r != ARCHIVE_OK) {
    fprintf(stderr, "error: failed to open file for writing: %s: %s\n",
            conv->tmpfile, strerror(archive_errno(conv->out)));
    r = archive_errno(conv->out);
    goto open_error;
  }

  return 0;

open_error:
  archive_write_free(conv->out);
  archive_read_free(conv->in);

  return -r;
}
Esempio n. 3
0
int main(int argc, char **argv) {
	int i;
	unsigned int version = 0, help = 0;
	char cpiotmpfile[] = CPIOTMPFILE;
	struct archive *archive;
	struct archive_entry *entry;
	struct stat st;
	char buff[64];
	int len, fdfile, fdarchive;
	DIR * dir;
	struct dirent * ent;
	char * filename, * path;
	off_t pathlength = 0;
	int8_t rc = EXIT_FAILURE;

	/* get command line options */
	while ((i = getopt_long(argc, argv, optstring, options_long, NULL)) != -1)
		switch (i) {
			case 'h':
				help++;
				break;
			case 'V':
				version++;
				break;
		}

	if (version > 0)
		printf("%s: %s v%s (compiled: " __DATE__ ", " __TIME__ ")\n", argv[0], PROGNAME, VERSION);

	if (help > 0)
		fprintf(stderr, "usage: %s [-h|--help] [-V|--version]\n", argv[0]);

	if (version > 0 || help > 0)
		return EXIT_SUCCESS;

	if ((fdarchive = mkstemp(cpiotmpfile)) < 0) {
		perror("mkstemp() failed");
		goto out10;
	}

	if ((archive = archive_write_new()) == NULL) {
		fprintf(stderr, "archive_write_new() failed.\n");
		goto out10;
	}

	if (archive_write_set_format_cpio_newc(archive) != ARCHIVE_OK) {
		fprintf(stderr, "archive_write_set_format_cpio_newc() failed.\n");
		goto out10;
	}

	if (archive_write_open_fd(archive, fdarchive) != ARCHIVE_OK) {
		fprintf(stderr, "archive_write_open_fd() failed.\n");
		goto out10;
	}

        while (1) {
		path = strdup(CHALLENGEDIR + 1);
		if (strstr(path + pathlength, "/") == NULL)
			break;

		*strstr(path + pathlength, "/") = 0;
		pathlength = strlen(path) + 1;

		if (add_dir(archive, path) < 0) {
			fprintf(stderr, "add_dir() failed");
			goto out10;
		}

		free(path);
	}

	if ((dir = opendir(CHALLENGEDIR)) == NULL) {
		perror("opendir() failed");
		goto out10;
	}

	while ((ent = readdir(dir)) != NULL) {
		filename = malloc(sizeof(CHALLENGEDIR) + strlen(ent->d_name) + 1);
		sprintf(filename, CHALLENGEDIR "%s", ent->d_name);

		if (stat(filename, &st) < 0) {
			perror("stat() failed");
			goto out10;
		}

		if (S_ISREG(st.st_mode)) {
			if ((entry = archive_entry_new()) == NULL) {
				fprintf(stderr, "archive_entry_new() failed.\n");
				goto out10;
			}

			/* these do not return exit code */
			archive_entry_set_pathname(entry, filename + 1);
			archive_entry_set_size(entry, st.st_size);
			archive_entry_set_filetype(entry, AE_IFREG);
			archive_entry_set_perm(entry, 0644);

			if (archive_write_header(archive, entry) != ARCHIVE_OK) {
				fprintf(stderr, "archive_write_header() failed");
				goto out10;
			}

			if ((fdfile = open(filename, O_RDONLY)) < 0) {
				perror("open() failed");
				goto out10;
			}

			if ((len = read(fdfile, buff, sizeof(buff))) < 0) {
				perror("read() failed");
				goto out10;
			}

			while (len > 0) {
				if (archive_write_data(archive, buff, len) < 0) {
					fprintf(stderr, "archive_write_data() failed");
					goto out10;
				}

				if ((len = read(fdfile, buff, sizeof(buff))) < 0) {
					perror("read() failed");
					goto out10;
				}
			}

			if (close(fdfile) < 0) {
				perror("close() failed");
				goto out10;
			}

			archive_entry_free(entry);
		}
		free(filename);
	}

	if (closedir(dir) < 0) {
		perror("closedir() failed");
		goto out10;
	}

	if (archive_write_close(archive) != ARCHIVE_OK) {
		fprintf(stderr, "archive_write_close() failed");
		goto out10;
	}

	if (archive_write_free(archive) != ARCHIVE_OK) {
		fprintf(stderr, "archive_write_free() failed");
		goto out10;
	}

	if (access(CPIOFILE, F_OK) == 0 && unlink(CPIOFILE) < 0) {
		perror("unkink() failed");
		goto out10;
	}

	if (rename(cpiotmpfile, CPIOFILE) < 0) {
		perror("rename() failed");
		goto out10;
	}

	rc = EXIT_SUCCESS;

out10:
	if (access(cpiotmpfile, F_OK) == 0)
		unlink(cpiotmpfile);

	return rc;
}