1228753Smm/*- 2232153Smm * Copyright (c) 2003-2010 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm 26228753Smm#include "archive_platform.h" 27228763Smm__FBSDID("$FreeBSD: stable/11/contrib/libarchive/libarchive/archive_write.c 370535 2021-09-10 08:34:36Z git2svn $"); 28228753Smm 29228753Smm/* 30228753Smm * This file contains the "essential" portions of the write API, that 31228753Smm * is, stuff that will essentially always be used by any client that 32232153Smm * actually needs to write an archive. Optional pieces have been, as 33228753Smm * far as possible, separated out into separate files to reduce 34228753Smm * needlessly bloating statically-linked clients. 35228753Smm */ 36228753Smm 37228753Smm#ifdef HAVE_SYS_WAIT_H 38228753Smm#include <sys/wait.h> 39228753Smm#endif 40232153Smm#ifdef HAVE_ERRNO_H 41232153Smm#include <errno.h> 42232153Smm#endif 43228753Smm#ifdef HAVE_LIMITS_H 44228753Smm#include <limits.h> 45228753Smm#endif 46228753Smm#include <stdio.h> 47228753Smm#ifdef HAVE_STDLIB_H 48228753Smm#include <stdlib.h> 49228753Smm#endif 50228753Smm#ifdef HAVE_STRING_H 51228753Smm#include <string.h> 52228753Smm#endif 53228753Smm#include <time.h> 54228753Smm#ifdef HAVE_UNISTD_H 55228753Smm#include <unistd.h> 56228753Smm#endif 57228753Smm 58228753Smm#include "archive.h" 59228753Smm#include "archive_entry.h" 60228753Smm#include "archive_private.h" 61228753Smm#include "archive_write_private.h" 62228753Smm 63228753Smmstatic struct archive_vtable *archive_write_vtable(void); 64228753Smm 65232153Smmstatic int _archive_filter_code(struct archive *, int); 66232153Smmstatic const char *_archive_filter_name(struct archive *, int); 67232153Smmstatic int64_t _archive_filter_bytes(struct archive *, int); 68232153Smmstatic int _archive_write_filter_count(struct archive *); 69228753Smmstatic int _archive_write_close(struct archive *); 70228773Smmstatic int _archive_write_free(struct archive *); 71228753Smmstatic int _archive_write_header(struct archive *, struct archive_entry *); 72228753Smmstatic int _archive_write_finish_entry(struct archive *); 73228753Smmstatic ssize_t _archive_write_data(struct archive *, const void *, size_t); 74228753Smm 75232153Smmstruct archive_none { 76232153Smm size_t buffer_size; 77232153Smm size_t avail; 78232153Smm char *buffer; 79232153Smm char *next; 80232153Smm}; 81232153Smm 82228753Smmstatic struct archive_vtable * 83228753Smmarchive_write_vtable(void) 84228753Smm{ 85228753Smm static struct archive_vtable av; 86228753Smm static int inited = 0; 87228753Smm 88228753Smm if (!inited) { 89228753Smm av.archive_close = _archive_write_close; 90232153Smm av.archive_filter_bytes = _archive_filter_bytes; 91232153Smm av.archive_filter_code = _archive_filter_code; 92232153Smm av.archive_filter_name = _archive_filter_name; 93232153Smm av.archive_filter_count = _archive_write_filter_count; 94228773Smm av.archive_free = _archive_write_free; 95228753Smm av.archive_write_header = _archive_write_header; 96228753Smm av.archive_write_finish_entry = _archive_write_finish_entry; 97228753Smm av.archive_write_data = _archive_write_data; 98232153Smm inited = 1; 99228753Smm } 100228753Smm return (&av); 101228753Smm} 102228753Smm 103228753Smm/* 104228753Smm * Allocate, initialize and return an archive object. 105228753Smm */ 106228753Smmstruct archive * 107228753Smmarchive_write_new(void) 108228753Smm{ 109228753Smm struct archive_write *a; 110228753Smm unsigned char *nulls; 111228753Smm 112311041Smm a = (struct archive_write *)calloc(1, sizeof(*a)); 113228753Smm if (a == NULL) 114228753Smm return (NULL); 115228753Smm a->archive.magic = ARCHIVE_WRITE_MAGIC; 116228753Smm a->archive.state = ARCHIVE_STATE_NEW; 117228753Smm a->archive.vtable = archive_write_vtable(); 118228753Smm /* 119228753Smm * The value 10240 here matches the traditional tar default, 120228753Smm * but is otherwise arbitrary. 121228753Smm * TODO: Set the default block size from the format selected. 122228753Smm */ 123228753Smm a->bytes_per_block = 10240; 124228753Smm a->bytes_in_last_block = -1; /* Default */ 125228753Smm 126228753Smm /* Initialize a block of nulls for padding purposes. */ 127228753Smm a->null_length = 1024; 128311041Smm nulls = (unsigned char *)calloc(1, a->null_length); 129228753Smm if (nulls == NULL) { 130228753Smm free(a); 131228753Smm return (NULL); 132228753Smm } 133228753Smm a->nulls = nulls; 134228753Smm return (&a->archive); 135228753Smm} 136228753Smm 137228753Smm/* 138228753Smm * Set the block size. Returns 0 if successful. 139228753Smm */ 140228753Smmint 141228753Smmarchive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block) 142228753Smm{ 143228753Smm struct archive_write *a = (struct archive_write *)_a; 144232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 145228753Smm ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block"); 146228753Smm a->bytes_per_block = bytes_per_block; 147228753Smm return (ARCHIVE_OK); 148228753Smm} 149228753Smm 150228753Smm/* 151228753Smm * Get the current block size. -1 if it has never been set. 152228753Smm */ 153228753Smmint 154228753Smmarchive_write_get_bytes_per_block(struct archive *_a) 155228753Smm{ 156228753Smm struct archive_write *a = (struct archive_write *)_a; 157232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 158228753Smm ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block"); 159228753Smm return (a->bytes_per_block); 160228753Smm} 161228753Smm 162228753Smm/* 163228753Smm * Set the size for the last block. 164228753Smm * Returns 0 if successful. 165228753Smm */ 166228753Smmint 167228753Smmarchive_write_set_bytes_in_last_block(struct archive *_a, int bytes) 168228753Smm{ 169228753Smm struct archive_write *a = (struct archive_write *)_a; 170232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 171228753Smm ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block"); 172228753Smm a->bytes_in_last_block = bytes; 173228753Smm return (ARCHIVE_OK); 174228753Smm} 175228753Smm 176228753Smm/* 177228753Smm * Return the value set above. -1 indicates it has not been set. 178228753Smm */ 179228753Smmint 180228753Smmarchive_write_get_bytes_in_last_block(struct archive *_a) 181228753Smm{ 182228753Smm struct archive_write *a = (struct archive_write *)_a; 183232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 184228753Smm ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block"); 185228753Smm return (a->bytes_in_last_block); 186228753Smm} 187228753Smm 188228753Smm/* 189228753Smm * dev/ino of a file to be rejected. Used to prevent adding 190228753Smm * an archive to itself recursively. 191228753Smm */ 192228753Smmint 193328827Smmarchive_write_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i) 194228753Smm{ 195228753Smm struct archive_write *a = (struct archive_write *)_a; 196232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 197228753Smm ARCHIVE_STATE_ANY, "archive_write_set_skip_file"); 198232153Smm a->skip_file_set = 1; 199228753Smm a->skip_file_dev = d; 200228753Smm a->skip_file_ino = i; 201228753Smm return (ARCHIVE_OK); 202228753Smm} 203228753Smm 204232153Smm/* 205232153Smm * Allocate and return the next filter structure. 206232153Smm */ 207232153Smmstruct archive_write_filter * 208232153Smm__archive_write_allocate_filter(struct archive *_a) 209232153Smm{ 210232153Smm struct archive_write *a = (struct archive_write *)_a; 211232153Smm struct archive_write_filter *f; 212228753Smm 213232153Smm f = calloc(1, sizeof(*f)); 214232153Smm f->archive = _a; 215358088Smm f->state = ARCHIVE_WRITE_FILTER_STATE_NEW; 216232153Smm if (a->filter_first == NULL) 217232153Smm a->filter_first = f; 218232153Smm else 219232153Smm a->filter_last->next_filter = f; 220232153Smm a->filter_last = f; 221232153Smm return f; 222232153Smm} 223232153Smm 224228753Smm/* 225232153Smm * Write data to a particular filter. 226232153Smm */ 227232153Smmint 228232153Smm__archive_write_filter(struct archive_write_filter *f, 229232153Smm const void *buff, size_t length) 230232153Smm{ 231232153Smm int r; 232358088Smm /* Never write to non-open filters */ 233358088Smm if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN) 234358088Smm return(ARCHIVE_FATAL); 235232153Smm if (length == 0) 236232153Smm return(ARCHIVE_OK); 237248616Smm if (f->write == NULL) 238313570Smm /* If unset, a fatal error has already occurred, so this filter 239248616Smm * didn't open. We cannot write anything. */ 240248616Smm return(ARCHIVE_FATAL); 241232153Smm r = (f->write)(f, buff, length); 242232153Smm f->bytes_written += length; 243232153Smm return (r); 244232153Smm} 245232153Smm 246232153Smm/* 247358088Smm * Recursive function for opening the filter chain 248358088Smm * Last filter is opened first 249232153Smm */ 250358088Smmstatic int 251232153Smm__archive_write_open_filter(struct archive_write_filter *f) 252232153Smm{ 253358088Smm int ret; 254358088Smm 255358088Smm ret = ARCHIVE_OK; 256358088Smm if (f->next_filter != NULL) 257358088Smm ret = __archive_write_open_filter(f->next_filter); 258358088Smm if (ret != ARCHIVE_OK) 259358088Smm return (ret); 260358088Smm if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW) 261358088Smm return (ARCHIVE_FATAL); 262358088Smm if (f->open == NULL) { 263358088Smm f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; 264232153Smm return (ARCHIVE_OK); 265358088Smm } 266358088Smm ret = (f->open)(f); 267358088Smm if (ret == ARCHIVE_OK) 268358088Smm f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; 269358088Smm else 270358088Smm f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; 271358088Smm return (ret); 272232153Smm} 273232153Smm 274232153Smm/* 275358088Smm * Open all filters 276232153Smm */ 277358088Smmstatic int 278358088Smm__archive_write_filters_open(struct archive_write *a) 279232153Smm{ 280358088Smm return (__archive_write_open_filter(a->filter_first)); 281232153Smm} 282232153Smm 283358088Smm/* 284358088Smm * Close all filtes 285358088Smm */ 286358088Smmstatic int 287358088Smm__archive_write_filters_close(struct archive_write *a) 288358088Smm{ 289358088Smm struct archive_write_filter *f; 290358088Smm int ret, ret1; 291358088Smm ret = ARCHIVE_OK; 292358088Smm for (f = a->filter_first; f != NULL; f = f->next_filter) { 293358088Smm /* Do not close filters that are not open */ 294358088Smm if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) { 295358088Smm if (f->close != NULL) { 296358088Smm ret1 = (f->close)(f); 297358088Smm if (ret1 < ret) 298358088Smm ret = ret1; 299358088Smm if (ret1 == ARCHIVE_OK) { 300358088Smm f->state = 301358088Smm ARCHIVE_WRITE_FILTER_STATE_CLOSED; 302358088Smm } else { 303358088Smm f->state = 304358088Smm ARCHIVE_WRITE_FILTER_STATE_FATAL; 305358088Smm } 306358088Smm } else 307358088Smm f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; 308358088Smm } 309358088Smm } 310358088Smm return (ret); 311358088Smm} 312358088Smm 313232153Smmint 314232153Smm__archive_write_output(struct archive_write *a, const void *buff, size_t length) 315232153Smm{ 316232153Smm return (__archive_write_filter(a->filter_first, buff, length)); 317232153Smm} 318232153Smm 319232153Smmint 320232153Smm__archive_write_nulls(struct archive_write *a, size_t length) 321232153Smm{ 322232153Smm if (length == 0) 323232153Smm return (ARCHIVE_OK); 324232153Smm 325232153Smm while (length > 0) { 326232153Smm size_t to_write = length < a->null_length ? length : a->null_length; 327232153Smm int r = __archive_write_output(a, a->nulls, to_write); 328232153Smm if (r < ARCHIVE_OK) 329232153Smm return (r); 330232153Smm length -= to_write; 331232153Smm } 332232153Smm return (ARCHIVE_OK); 333232153Smm} 334232153Smm 335232153Smmstatic int 336232153Smmarchive_write_client_open(struct archive_write_filter *f) 337232153Smm{ 338232153Smm struct archive_write *a = (struct archive_write *)f->archive; 339232153Smm struct archive_none *state; 340232153Smm void *buffer; 341232153Smm size_t buffer_size; 342358088Smm int ret; 343232153Smm 344232153Smm f->bytes_per_block = archive_write_get_bytes_per_block(f->archive); 345232153Smm f->bytes_in_last_block = 346232153Smm archive_write_get_bytes_in_last_block(f->archive); 347232153Smm buffer_size = f->bytes_per_block; 348232153Smm 349232153Smm state = (struct archive_none *)calloc(1, sizeof(*state)); 350232153Smm buffer = (char *)malloc(buffer_size); 351232153Smm if (state == NULL || buffer == NULL) { 352232153Smm free(state); 353232153Smm free(buffer); 354232153Smm archive_set_error(f->archive, ENOMEM, 355232153Smm "Can't allocate data for output buffering"); 356232153Smm return (ARCHIVE_FATAL); 357232153Smm } 358232153Smm 359232153Smm state->buffer_size = buffer_size; 360232153Smm state->buffer = buffer; 361232153Smm state->next = state->buffer; 362232153Smm state->avail = state->buffer_size; 363232153Smm f->data = state; 364232153Smm 365232153Smm if (a->client_opener == NULL) 366232153Smm return (ARCHIVE_OK); 367358088Smm ret = a->client_opener(f->archive, a->client_data); 368358088Smm if (ret != ARCHIVE_OK) { 369358088Smm free(state->buffer); 370358088Smm free(state); 371358088Smm f->data = NULL; 372358088Smm } 373358088Smm return (ret); 374232153Smm} 375232153Smm 376232153Smmstatic int 377232153Smmarchive_write_client_write(struct archive_write_filter *f, 378232153Smm const void *_buff, size_t length) 379232153Smm{ 380232153Smm struct archive_write *a = (struct archive_write *)f->archive; 381232153Smm struct archive_none *state = (struct archive_none *)f->data; 382232153Smm const char *buff = (const char *)_buff; 383232153Smm ssize_t remaining, to_copy; 384232153Smm ssize_t bytes_written; 385232153Smm 386232153Smm remaining = length; 387232153Smm 388232153Smm /* 389232153Smm * If there is no buffer for blocking, just pass the data 390232153Smm * straight through to the client write callback. In 391232153Smm * particular, this supports "no write delay" operation for 392232153Smm * special applications. Just set the block size to zero. 393232153Smm */ 394232153Smm if (state->buffer_size == 0) { 395232153Smm while (remaining > 0) { 396232153Smm bytes_written = (a->client_writer)(&a->archive, 397232153Smm a->client_data, buff, remaining); 398232153Smm if (bytes_written <= 0) 399232153Smm return (ARCHIVE_FATAL); 400232153Smm remaining -= bytes_written; 401232153Smm buff += bytes_written; 402232153Smm } 403232153Smm return (ARCHIVE_OK); 404232153Smm } 405232153Smm 406232153Smm /* If the copy buffer isn't empty, try to fill it. */ 407232153Smm if (state->avail < state->buffer_size) { 408232153Smm /* If buffer is not empty... */ 409232153Smm /* ... copy data into buffer ... */ 410232153Smm to_copy = ((size_t)remaining > state->avail) ? 411232153Smm state->avail : (size_t)remaining; 412232153Smm memcpy(state->next, buff, to_copy); 413232153Smm state->next += to_copy; 414232153Smm state->avail -= to_copy; 415232153Smm buff += to_copy; 416232153Smm remaining -= to_copy; 417232153Smm /* ... if it's full, write it out. */ 418232153Smm if (state->avail == 0) { 419232153Smm char *p = state->buffer; 420232153Smm size_t to_write = state->buffer_size; 421232153Smm while (to_write > 0) { 422232153Smm bytes_written = (a->client_writer)(&a->archive, 423232153Smm a->client_data, p, to_write); 424232153Smm if (bytes_written <= 0) 425232153Smm return (ARCHIVE_FATAL); 426232153Smm if ((size_t)bytes_written > to_write) { 427232153Smm archive_set_error(&(a->archive), 428232153Smm -1, "write overrun"); 429232153Smm return (ARCHIVE_FATAL); 430232153Smm } 431232153Smm p += bytes_written; 432232153Smm to_write -= bytes_written; 433232153Smm } 434232153Smm state->next = state->buffer; 435232153Smm state->avail = state->buffer_size; 436232153Smm } 437232153Smm } 438232153Smm 439238856Smm while ((size_t)remaining >= state->buffer_size) { 440232153Smm /* Write out full blocks directly to client. */ 441232153Smm bytes_written = (a->client_writer)(&a->archive, 442232153Smm a->client_data, buff, state->buffer_size); 443232153Smm if (bytes_written <= 0) 444232153Smm return (ARCHIVE_FATAL); 445232153Smm buff += bytes_written; 446232153Smm remaining -= bytes_written; 447232153Smm } 448232153Smm 449232153Smm if (remaining > 0) { 450232153Smm /* Copy last bit into copy buffer. */ 451232153Smm memcpy(state->next, buff, remaining); 452232153Smm state->next += remaining; 453232153Smm state->avail -= remaining; 454232153Smm } 455232153Smm return (ARCHIVE_OK); 456232153Smm} 457232153Smm 458232153Smmstatic int 459368707Smmarchive_write_client_free(struct archive_write_filter *f) 460368707Smm{ 461368707Smm struct archive_write *a = (struct archive_write *)f->archive; 462368707Smm 463368707Smm if (a->client_freer) 464368707Smm (*a->client_freer)(&a->archive, a->client_data); 465368707Smm a->client_data = NULL; 466368707Smm 467368707Smm /* Clear passphrase. */ 468368707Smm if (a->passphrase != NULL) { 469368707Smm memset(a->passphrase, 0, strlen(a->passphrase)); 470368707Smm free(a->passphrase); 471368707Smm a->passphrase = NULL; 472368707Smm } 473368707Smm 474368707Smm return (ARCHIVE_OK); 475368707Smm} 476368707Smm 477368707Smmstatic int 478232153Smmarchive_write_client_close(struct archive_write_filter *f) 479232153Smm{ 480232153Smm struct archive_write *a = (struct archive_write *)f->archive; 481232153Smm struct archive_none *state = (struct archive_none *)f->data; 482232153Smm ssize_t block_length; 483232153Smm ssize_t target_block_length; 484232153Smm ssize_t bytes_written; 485370535Sgit2svn size_t to_write; 486370535Sgit2svn char *p; 487232153Smm int ret = ARCHIVE_OK; 488232153Smm 489232153Smm /* If there's pending data, pad and write the last block */ 490232153Smm if (state->next != state->buffer) { 491232153Smm block_length = state->buffer_size - state->avail; 492232153Smm 493232153Smm /* Tricky calculation to determine size of last block */ 494232153Smm if (a->bytes_in_last_block <= 0) 495232153Smm /* Default or Zero: pad to full block */ 496232153Smm target_block_length = a->bytes_per_block; 497232153Smm else 498232153Smm /* Round to next multiple of bytes_in_last_block. */ 499232153Smm target_block_length = a->bytes_in_last_block * 500232153Smm ( (block_length + a->bytes_in_last_block - 1) / 501232153Smm a->bytes_in_last_block); 502232153Smm if (target_block_length > a->bytes_per_block) 503232153Smm target_block_length = a->bytes_per_block; 504232153Smm if (block_length < target_block_length) { 505232153Smm memset(state->next, 0, 506232153Smm target_block_length - block_length); 507232153Smm block_length = target_block_length; 508232153Smm } 509370535Sgit2svn p = state->buffer; 510370535Sgit2svn to_write = block_length; 511370535Sgit2svn while (to_write > 0) { 512370535Sgit2svn bytes_written = (a->client_writer)(&a->archive, 513370535Sgit2svn a->client_data, p, to_write); 514370535Sgit2svn if (bytes_written <= 0) { 515370535Sgit2svn ret = ARCHIVE_FATAL; 516370535Sgit2svn break; 517370535Sgit2svn } 518370535Sgit2svn if ((size_t)bytes_written > to_write) { 519370535Sgit2svn archive_set_error(&(a->archive), 520370535Sgit2svn -1, "write overrun"); 521370535Sgit2svn ret = ARCHIVE_FATAL; 522370535Sgit2svn break; 523370535Sgit2svn } 524370535Sgit2svn p += bytes_written; 525370535Sgit2svn to_write -= bytes_written; 526370535Sgit2svn } 527232153Smm } 528232153Smm if (a->client_closer) 529232153Smm (*a->client_closer)(&a->archive, a->client_data); 530232153Smm free(state->buffer); 531232153Smm free(state); 532368707Smm 533358088Smm /* Clear the close handler myself not to be called again. */ 534358088Smm f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; 535232153Smm return (ret); 536232153Smm} 537232153Smm 538232153Smm/* 539228753Smm * Open the archive using the current settings. 540228753Smm */ 541228753Smmint 542368707Smmarchive_write_open2(struct archive *_a, void *client_data, 543228753Smm archive_open_callback *opener, archive_write_callback *writer, 544368707Smm archive_close_callback *closer, archive_free_callback *freer) 545228753Smm{ 546228753Smm struct archive_write *a = (struct archive_write *)_a; 547232153Smm struct archive_write_filter *client_filter; 548232153Smm int ret, r1; 549228753Smm 550232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 551228753Smm ARCHIVE_STATE_NEW, "archive_write_open"); 552228753Smm archive_clear_error(&a->archive); 553232153Smm 554228753Smm a->client_writer = writer; 555228753Smm a->client_opener = opener; 556228753Smm a->client_closer = closer; 557368707Smm a->client_freer = freer; 558232153Smm a->client_data = client_data; 559232153Smm 560232153Smm client_filter = __archive_write_allocate_filter(_a); 561232153Smm client_filter->open = archive_write_client_open; 562232153Smm client_filter->write = archive_write_client_write; 563232153Smm client_filter->close = archive_write_client_close; 564368707Smm client_filter->free = archive_write_client_free; 565232153Smm 566358088Smm ret = __archive_write_filters_open(a); 567232153Smm if (ret < ARCHIVE_WARN) { 568358088Smm r1 = __archive_write_filters_close(a); 569358088Smm __archive_write_filters_free(_a); 570232153Smm return (r1 < ret ? r1 : ret); 571232153Smm } 572232153Smm 573232153Smm a->archive.state = ARCHIVE_STATE_HEADER; 574232153Smm if (a->format_init) 575228753Smm ret = (a->format_init)(a); 576228753Smm return (ret); 577228753Smm} 578228753Smm 579368707Smmint 580368707Smmarchive_write_open(struct archive *_a, void *client_data, 581368707Smm archive_open_callback *opener, archive_write_callback *writer, 582368707Smm archive_close_callback *closer) 583368707Smm{ 584368707Smm return archive_write_open2(_a, client_data, opener, writer, 585368707Smm closer, NULL); 586368707Smm} 587368707Smm 588228753Smm/* 589228753Smm * Close out the archive. 590228753Smm */ 591228753Smmstatic int 592228753Smm_archive_write_close(struct archive *_a) 593228753Smm{ 594228753Smm struct archive_write *a = (struct archive_write *)_a; 595228753Smm int r = ARCHIVE_OK, r1 = ARCHIVE_OK; 596228753Smm 597232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 598232153Smm ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, 599232153Smm "archive_write_close"); 600232153Smm if (a->archive.state == ARCHIVE_STATE_NEW 601232153Smm || a->archive.state == ARCHIVE_STATE_CLOSED) 602232153Smm return (ARCHIVE_OK); /* Okay to close() when not open. */ 603228753Smm 604232153Smm archive_clear_error(&a->archive); 605232153Smm 606299529Smm /* Finish the last entry if a finish callback is specified */ 607299529Smm if (a->archive.state == ARCHIVE_STATE_DATA 608299529Smm && a->format_finish_entry != NULL) 609228753Smm r = ((a->format_finish_entry)(a)); 610228753Smm 611228753Smm /* Finish off the archive. */ 612232153Smm /* TODO: have format closers invoke compression close. */ 613232153Smm if (a->format_close != NULL) { 614232153Smm r1 = (a->format_close)(a); 615228753Smm if (r1 < r) 616228753Smm r = r1; 617228753Smm } 618228753Smm 619232153Smm /* Finish the compression and close the stream. */ 620358088Smm r1 = __archive_write_filters_close(a); 621232153Smm if (r1 < r) 622232153Smm r = r1; 623228753Smm 624232153Smm if (a->archive.state != ARCHIVE_STATE_FATAL) 625232153Smm a->archive.state = ARCHIVE_STATE_CLOSED; 626232153Smm return (r); 627232153Smm} 628232153Smm 629232153Smmstatic int 630232153Smm_archive_write_filter_count(struct archive *_a) 631232153Smm{ 632232153Smm struct archive_write *a = (struct archive_write *)_a; 633232153Smm struct archive_write_filter *p = a->filter_first; 634232153Smm int count = 0; 635232153Smm while(p) { 636232153Smm count++; 637232153Smm p = p->next_filter; 638228753Smm } 639232153Smm return count; 640232153Smm} 641228753Smm 642232153Smmvoid 643232153Smm__archive_write_filters_free(struct archive *_a) 644232153Smm{ 645232153Smm struct archive_write *a = (struct archive_write *)_a; 646232153Smm int r = ARCHIVE_OK, r1; 647232153Smm 648232153Smm while (a->filter_first != NULL) { 649232153Smm struct archive_write_filter *next 650232153Smm = a->filter_first->next_filter; 651232153Smm if (a->filter_first->free != NULL) { 652232153Smm r1 = (*a->filter_first->free)(a->filter_first); 653232153Smm if (r > r1) 654232153Smm r = r1; 655232153Smm } 656232153Smm free(a->filter_first); 657232153Smm a->filter_first = next; 658228753Smm } 659232153Smm a->filter_last = NULL; 660228753Smm} 661228753Smm 662228753Smm/* 663228753Smm * Destroy the archive structure. 664232153Smm * 665232153Smm * Be careful: user might just call write_new and then write_free. 666232153Smm * Don't assume we actually wrote anything or performed any non-trivial 667232153Smm * initialization. 668228753Smm */ 669228753Smmstatic int 670228773Smm_archive_write_free(struct archive *_a) 671228753Smm{ 672228753Smm struct archive_write *a = (struct archive_write *)_a; 673232153Smm int r = ARCHIVE_OK, r1; 674228753Smm 675232153Smm if (_a == NULL) 676232153Smm return (ARCHIVE_OK); 677232153Smm /* It is okay to call free() in state FATAL. */ 678232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 679232153Smm ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free"); 680232153Smm if (a->archive.state != ARCHIVE_STATE_FATAL) 681228753Smm r = archive_write_close(&a->archive); 682228753Smm 683232153Smm /* Release format resources. */ 684232153Smm if (a->format_free != NULL) { 685232153Smm r1 = (a->format_free)(a); 686232153Smm if (r1 < r) 687232153Smm r = r1; 688232153Smm } 689232153Smm 690232153Smm __archive_write_filters_free(_a); 691232153Smm 692228753Smm /* Release various dynamic buffers. */ 693228753Smm free((void *)(uintptr_t)(const void *)a->nulls); 694228753Smm archive_string_free(&a->archive.error_string); 695299529Smm if (a->passphrase != NULL) { 696299529Smm /* A passphrase should be cleaned. */ 697299529Smm memset(a->passphrase, 0, strlen(a->passphrase)); 698299529Smm free(a->passphrase); 699299529Smm } 700228753Smm a->archive.magic = 0; 701232153Smm __archive_clean(&a->archive); 702228753Smm free(a); 703228753Smm return (r); 704228753Smm} 705228753Smm 706228753Smm/* 707228753Smm * Write the appropriate header. 708228753Smm */ 709228753Smmstatic int 710228753Smm_archive_write_header(struct archive *_a, struct archive_entry *entry) 711228753Smm{ 712228753Smm struct archive_write *a = (struct archive_write *)_a; 713228753Smm int ret, r2; 714228753Smm 715232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 716228753Smm ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header"); 717228753Smm archive_clear_error(&a->archive); 718228753Smm 719232153Smm if (a->format_write_header == NULL) { 720232153Smm archive_set_error(&(a->archive), -1, 721232153Smm "Format must be set before you can write to an archive."); 722232153Smm a->archive.state = ARCHIVE_STATE_FATAL; 723232153Smm return (ARCHIVE_FATAL); 724232153Smm } 725232153Smm 726228753Smm /* In particular, "retry" and "fatal" get returned immediately. */ 727228753Smm ret = archive_write_finish_entry(&a->archive); 728232153Smm if (ret == ARCHIVE_FATAL) { 729232153Smm a->archive.state = ARCHIVE_STATE_FATAL; 730232153Smm return (ARCHIVE_FATAL); 731232153Smm } 732228753Smm if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN) 733228753Smm return (ret); 734228753Smm 735232153Smm if (a->skip_file_set && 736232153Smm archive_entry_dev_is_set(entry) && 737232153Smm archive_entry_ino_is_set(entry) && 738238856Smm archive_entry_dev(entry) == (dev_t)a->skip_file_dev && 739228753Smm archive_entry_ino64(entry) == a->skip_file_ino) { 740228753Smm archive_set_error(&a->archive, 0, 741228753Smm "Can't add archive to itself"); 742228753Smm return (ARCHIVE_FAILED); 743228753Smm } 744228753Smm 745228753Smm /* Format and write header. */ 746228753Smm r2 = ((a->format_write_header)(a, entry)); 747299529Smm if (r2 == ARCHIVE_FAILED) { 748299529Smm return (ARCHIVE_FAILED); 749299529Smm } 750232153Smm if (r2 == ARCHIVE_FATAL) { 751232153Smm a->archive.state = ARCHIVE_STATE_FATAL; 752232153Smm return (ARCHIVE_FATAL); 753232153Smm } 754228753Smm if (r2 < ret) 755228753Smm ret = r2; 756228753Smm 757228753Smm a->archive.state = ARCHIVE_STATE_DATA; 758228753Smm return (ret); 759228753Smm} 760228753Smm 761228753Smmstatic int 762228753Smm_archive_write_finish_entry(struct archive *_a) 763228753Smm{ 764228753Smm struct archive_write *a = (struct archive_write *)_a; 765228753Smm int ret = ARCHIVE_OK; 766228753Smm 767232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 768228753Smm ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, 769228753Smm "archive_write_finish_entry"); 770299529Smm if (a->archive.state & ARCHIVE_STATE_DATA 771299529Smm && a->format_finish_entry != NULL) 772228753Smm ret = (a->format_finish_entry)(a); 773228753Smm a->archive.state = ARCHIVE_STATE_HEADER; 774228753Smm return (ret); 775228753Smm} 776228753Smm 777228753Smm/* 778228753Smm * Note that the compressor is responsible for blocking. 779228753Smm */ 780228753Smmstatic ssize_t 781228753Smm_archive_write_data(struct archive *_a, const void *buff, size_t s) 782228753Smm{ 783228753Smm struct archive_write *a = (struct archive_write *)_a; 784248664Smm const size_t max_write = INT_MAX; 785248664Smm 786232153Smm archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, 787228753Smm ARCHIVE_STATE_DATA, "archive_write_data"); 788248664Smm /* In particular, this catches attempts to pass negative values. */ 789248664Smm if (s > max_write) 790248664Smm s = max_write; 791228753Smm archive_clear_error(&a->archive); 792228753Smm return ((a->format_write_data)(a, buff, s)); 793228753Smm} 794232153Smm 795232153Smmstatic struct archive_write_filter * 796232153Smmfilter_lookup(struct archive *_a, int n) 797232153Smm{ 798232153Smm struct archive_write *a = (struct archive_write *)_a; 799232153Smm struct archive_write_filter *f = a->filter_first; 800232153Smm if (n == -1) 801232153Smm return a->filter_last; 802232153Smm if (n < 0) 803232153Smm return NULL; 804232153Smm while (n > 0 && f != NULL) { 805232153Smm f = f->next_filter; 806232153Smm --n; 807232153Smm } 808232153Smm return f; 809232153Smm} 810232153Smm 811232153Smmstatic int 812232153Smm_archive_filter_code(struct archive *_a, int n) 813232153Smm{ 814232153Smm struct archive_write_filter *f = filter_lookup(_a, n); 815232153Smm return f == NULL ? -1 : f->code; 816232153Smm} 817232153Smm 818232153Smmstatic const char * 819232153Smm_archive_filter_name(struct archive *_a, int n) 820232153Smm{ 821232153Smm struct archive_write_filter *f = filter_lookup(_a, n); 822299529Smm return f != NULL ? f->name : NULL; 823232153Smm} 824232153Smm 825232153Smmstatic int64_t 826232153Smm_archive_filter_bytes(struct archive *_a, int n) 827232153Smm{ 828232153Smm struct archive_write_filter *f = filter_lookup(_a, n); 829232153Smm return f == NULL ? -1 : f->bytes_written; 830232153Smm} 831