//
// tardy - a tar post-processor
// Copyright (C) 1998, 1999, 2002-2004, 2008, 2009, 2011 Peter Miller
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

#include <libtardy/ac/assert.h>
#include <libtardy/ac/errno.h>
#include <libtardy/ac/stdio.h>
#include <libtardy/ac/string.h>
#include <libexplain/output.h>

#include <libtardy/tar/output.h>


tar_output::~tar_output()
{
}


tar_output::tar_output()
{
}


tar_output::tar_output(const tar_output &)
{
    assert(!"should not reach here");
}


tar_output &
tar_output::operator=(const tar_output &)
{
    assert(!"should not reach here");
    return *this;
}


void
tar_output::fatal(const char *fmt, ...)
    const
{
    va_list ap;
    va_start(ap, fmt);
    char buffer[2000];
    vsnprintf(buffer, sizeof(buffer), fmt, ap);
    va_end(ap);
    explain_output_error_and_die
    (
        "%s: %s {%s}",
        filename().c_str(),
        buffer,
        get_format_name()
    );
}


void
tar_output::write_data_padding()
{
    // none by default
}


void
tar_output::write_header_padding()
{
    // same alignment as data by default
    write_data_padding();
}


void
tar_output::write_archive_begin()
{
    // none by default
}


void
tar_output::write_archive_end()
{
    // none by default
}


void
tar_output::set_block_size(long)
{
    // ignore by default
}


int
tar_output::calculate_mode(const tar_header &h)
    const
{
    //
    // Don't use the native UNIX defintions, because
    // (a) this may not be UNIX, and
    // (b) the vendor may have gratuitously changed things.
    //
    int hibits;
    hibits = 0100000;
    switch (h.type)
    {
    case tar_header::type_socket:
        hibits = 0140000;
        break;

    case tar_header::type_link_symbolic:
        hibits = 0120000;
        break;

    case tar_header::type_normal:
    case tar_header::type_normal_contiguous:
    case tar_header::type_link_hard:
        hibits = 0100000;
        break;

    case tar_header::type_device_block:
        hibits = 0060000;
        break;

    case tar_header::type_directory:
        hibits = 0040000;
        break;

    case tar_header::type_device_character:
        hibits = 0020000;
        break;

    case tar_header::type_fifo:
        hibits = 0010000;
        break;

    case tar_header::type_normal_gzipped:
        fatal("gzipped type not supported");
        break;
    }
    return (h.mode | hibits);
}
