/* * Setup callback. */ static int archive_compressor_program_open(struct archive_write_filter *f) { struct private_data *data = (struct private_data *)f->data; int ret; ret = __archive_write_open_filter(f->next_filter); if (ret != ARCHIVE_OK) return (ret); if (data->child_buf == NULL) { data->child_buf_len = 65536; data->child_buf_avail = 0; data->child_buf = malloc(data->child_buf_len); if (data->child_buf == NULL) { archive_set_error(f->archive, ENOMEM, "Can't allocate compression buffer"); return (ARCHIVE_FATAL); } } if ((data->child = __archive_create_child(data->cmd, &data->child_stdin, &data->child_stdout)) == -1) { archive_set_error(f->archive, EINVAL, "Can't initialise filter"); return (ARCHIVE_FATAL); } f->write = archive_compressor_program_write; f->close = archive_compressor_program_close; f->free = archive_compressor_program_free; return (0); }
/* * Setup callback. */ static int archive_compressor_program_init(struct archive_write *a) { int ret; struct private_data *state; static const char *prefix = "Program: "; char *cmd = a->compressor.config; if (a->client_opener != NULL) { ret = (a->client_opener)(&a->archive, a->client_data); if (ret != ARCHIVE_OK) return (ret); } state = (struct private_data *)malloc(sizeof(*state)); if (state == NULL) { archive_set_error(&a->archive, ENOMEM, "Can't allocate data for compression"); return (ARCHIVE_FATAL); } memset(state, 0, sizeof(*state)); a->archive.compression_code = ARCHIVE_COMPRESSION_PROGRAM; state->description = (char *)malloc(strlen(prefix) + strlen(cmd) + 1); strcpy(state->description, prefix); strcat(state->description, cmd); a->archive.compression_name = state->description; state->child_buf_len = a->bytes_per_block; state->child_buf_avail = 0; state->child_buf = malloc(state->child_buf_len); if (state->child_buf == NULL) { archive_set_error(&a->archive, ENOMEM, "Can't allocate data for compression buffer"); free(state); return (ARCHIVE_FATAL); } if ((state->child = __archive_create_child(cmd, &state->child_stdin, &state->child_stdout)) == -1) { archive_set_error(&a->archive, EINVAL, "Can't initialise filter"); free(state->child_buf); free(state); return (ARCHIVE_FATAL); } a->compressor.write = archive_compressor_program_write; a->compressor.finish = archive_compressor_program_finish; a->compressor.data = state; return (0); }
int __archive_read_program(struct archive_read_filter *self, const char *cmd) { struct program_filter *state; static const size_t out_buf_len = 65536; char *out_buf; char *description; const char *prefix = "Program: "; state = (struct program_filter *)calloc(1, sizeof(*state)); out_buf = (char *)malloc(out_buf_len); description = (char *)malloc(strlen(prefix) + strlen(cmd) + 1); if (state == NULL || out_buf == NULL || description == NULL) { tk_archive_set_error(&self->archive->archive, ENOMEM, "Can't allocate input data"); free(state); free(out_buf); free(description); return (ARCHIVE_FATAL); } self->code = ARCHIVE_COMPRESSION_PROGRAM; state->description = description; strcpy(state->description, prefix); strcat(state->description, cmd); self->name = state->description; state->out_buf = out_buf; state->out_buf_len = out_buf_len; if ((state->child = __archive_create_child(cmd, &state->child_stdin, &state->child_stdout)) == -1) { free(state->out_buf); free(state); tk_archive_set_error(&self->archive->archive, EINVAL, "Can't initialise filter"); return (ARCHIVE_FATAL); } self->data = state; self->read = program_filter_read; self->skip = NULL; self->close = program_filter_close; /* XXX Check that we can read at least one byte? */ return (ARCHIVE_OK); }
int __archive_write_program_open(struct archive_write_filter *f, struct archive_write_program_data *data, const char *cmd) { pid_t child; int ret; ret = __archive_write_open_filter(f->next_filter); if (ret != ARCHIVE_OK) return (ret); if (data->child_buf == NULL) { data->child_buf_len = 65536; data->child_buf_avail = 0; data->child_buf = malloc(data->child_buf_len); if (data->child_buf == NULL) { archive_set_error(f->archive, ENOMEM, "Can't allocate compression buffer"); return (ARCHIVE_FATAL); } } child = __archive_create_child(cmd, &data->child_stdin, &data->child_stdout); if (child == -1) { archive_set_error(f->archive, EINVAL, "Can't initialise filter"); return (ARCHIVE_FATAL); } #if defined(_WIN32) && !defined(__CYGWIN__) data->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child); if (data->child == NULL) { close(data->child_stdin); data->child_stdin = -1; close(data->child_stdout); data->child_stdout = -1; archive_set_error(f->archive, EINVAL, "Can't initialise filter"); return (ARCHIVE_FATAL); } #else data->child = child; #endif return (ARCHIVE_OK); }
int __archive_read_program(struct archive_read_filter *self, const char *cmd) { struct program_filter *state; static const size_t out_buf_len = 65536; char *out_buf; const char *prefix = "Program: "; pid_t child; size_t l; l = strlen(prefix) + strlen(cmd) + 1; state = (struct program_filter *)calloc(1, sizeof(*state)); out_buf = (char *)malloc(out_buf_len); if (state == NULL || out_buf == NULL || archive_string_ensure(&state->description, l) == NULL) { archive_set_error(&self->archive->archive, ENOMEM, "Can't allocate input data"); if (state != NULL) { archive_string_free(&state->description); free(state); } free(out_buf); return (ARCHIVE_FATAL); } archive_strcpy(&state->description, prefix); archive_strcat(&state->description, cmd); self->code = ARCHIVE_FILTER_PROGRAM; self->name = state->description.s; state->out_buf = out_buf; state->out_buf_len = out_buf_len; child = __archive_create_child(cmd, &state->child_stdin, &state->child_stdout); if (child == -1) { free(state->out_buf); free(state); archive_set_error(&self->archive->archive, EINVAL, "Can't initialize filter; unable to run program \"%s\"", cmd); return (ARCHIVE_FATAL); } #if defined(_WIN32) && !defined(__CYGWIN__) state->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child); if (state->child == NULL) { child_stop(self, state); free(state->out_buf); free(state); archive_set_error(&self->archive->archive, EINVAL, "Can't initialize filter; unable to run program \"%s\"", cmd); return (ARCHIVE_FATAL); } #else state->child = child; #endif self->data = state; self->read = program_filter_read; self->skip = NULL; self->close = program_filter_close; /* XXX Check that we can read at least one byte? */ return (ARCHIVE_OK); }