[Cmake-commits] [cmake-commits] hoffman committed CMakeLists.txt NONE 1.1 Makefile NONE 1.1 main.c NONE 1.1 test.h NONE 1.1 test_0.c NONE 1.1 test_basic.c NONE 1.1 test_cmdline.c NONE 1.1 test_format_newc.c NONE 1.1 test_gcpio_compat.c NONE 1.1 test_gcpio_compat_ref.bin.uu NONE 1.1 test_gcpio_compat_ref.crc.uu NONE 1.1 test_gcpio_compat_ref.newc.uu NONE 1.1 test_gcpio_compat_ref.ustar.uu NONE 1.1 test_gcpio_compat_ref_nosym.bin.uu NONE 1.1 test_gcpio_compat_ref_nosym.crc.uu NONE 1.1 test_gcpio_compat_ref_nosym.newc.uu NONE 1.1 test_gcpio_compat_ref_nosym.ustar.uu NONE 1.1 test_option_B_upper.c NONE 1.1 test_option_C_upper.c NONE 1.1 test_option_J_upper.c NONE 1.1 test_option_L_upper.c NONE 1.1 test_option_Z_upper.c NONE 1.1 test_option_a.c NONE 1.1 test_option_c.c NONE 1.1 test_option_d.c NONE 1.1 test_option_f.c NONE 1.1 test_option_f.cpio.uu NONE 1.1 test_option_help.c NONE 1.1 test_option_l.c NONE 1.1 test_option_lzma.c NONE 1.1 test_option_m.c NONE 1.1 test_option_m.cpio.uu NONE 1.1 test_option_t.c NONE 1.1 test_option_t.cpio.uu NONE 1.1 test_option_t.stdout.uu NONE 1.1 test_option_tv.stdout.uu NONE 1.1 test_option_u.c NONE 1.1 test_option_version.c NONE 1.1 test_option_y.c NONE 1.1 test_option_z.c NONE 1.1 test_owner_parse.c NONE 1.1 test_passthrough_dotdot.c NONE 1.1 test_passthrough_reverse.c NONE 1.1 test_pathmatch.c NONE 1.1

cmake-commits at cmake.org cmake-commits at cmake.org
Fri Oct 30 13:09:54 EDT 2009


Update of /cvsroot/CMake/CMake/Utilities/cmlibarchive/cpio/test
In directory public:/mounts/ram/cvs-serv26614/Utilities/cmlibarchive/cpio/test

Added Files:
	CMakeLists.txt Makefile main.c test.h test_0.c test_basic.c 
	test_cmdline.c test_format_newc.c test_gcpio_compat.c 
	test_gcpio_compat_ref.bin.uu test_gcpio_compat_ref.crc.uu 
	test_gcpio_compat_ref.newc.uu test_gcpio_compat_ref.ustar.uu 
	test_gcpio_compat_ref_nosym.bin.uu 
	test_gcpio_compat_ref_nosym.crc.uu 
	test_gcpio_compat_ref_nosym.newc.uu 
	test_gcpio_compat_ref_nosym.ustar.uu test_option_B_upper.c 
	test_option_C_upper.c test_option_J_upper.c 
	test_option_L_upper.c test_option_Z_upper.c test_option_a.c 
	test_option_c.c test_option_d.c test_option_f.c 
	test_option_f.cpio.uu test_option_help.c test_option_l.c 
	test_option_lzma.c test_option_m.c test_option_m.cpio.uu 
	test_option_t.c test_option_t.cpio.uu test_option_t.stdout.uu 
	test_option_tv.stdout.uu test_option_u.c test_option_version.c 
	test_option_y.c test_option_z.c test_owner_parse.c 
	test_passthrough_dotdot.c test_passthrough_reverse.c 
	test_pathmatch.c 
Log Message:
Switch to using libarchive from libtar for cpack and cmake -E tar

This allows for a built in bzip and zip capability, so external tools 
will not be needed for these packagers.  The cmake -E tar xf should be
able to handle all compression types now as well.



--- NEW FILE: test_option_a.c ---
/*-
 * Copyright (c) 2003-2008 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <sys/utime.h>
#else
#include <utime.h>
#endif
__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_option_a.c,v 1.3 2008/08/24 06:21:00 kientzle Exp $");

static struct {
    const char *name;
    time_t atime_sec;
} files[] = {
    { "f0", 0 },
    { "f1", 0 },
    { "f2", 0 },
    { "f3", 0 },
    { "f4", 0 },
    { "f5", 0 }
};

/*
 * Create a bunch of test files and record their atimes.
 * For the atime preserve/change tests, the files must have
 * atimes in the past.  We can accomplish this by explicitly invoking
 * utime() on platforms that support it or by simply sleeping
 * for a second after creating the files.  (Creating all of the files
 * at once means we only need to sleep once.)
 */
static void
test_create(void)
{
    struct stat st;
    struct utimbuf times;
    static const int numfiles = sizeof(files) / sizeof(files[0]);
    int i;

    for (i = 0; i < numfiles; ++i) {
        /*
         * Note: Have to write at least one byte to the file.
         * cpio doesn't bother reading the file if it's zero length,
         * so the atime never gets changed in that case, which
         * makes the tests below rather pointless.
         */
        assertMakeFile(files[i].name, 0644, "a");

        /* If utime() isn't supported on your platform, just
         * #ifdef this section out.  Most of the test below is
         * still valid. */
        memset(&times, 0, sizeof(times));
        times.actime = 1;
        times.modtime = 3;
        assertEqualInt(0, utime(files[i].name, &times));

        /* Record whatever atime the file ended up with. */
        /* If utime() is available, this should be 1, but there's
         * no harm in being careful. */
        assertEqualInt(0, stat(files[i].name, &st));
        files[i].atime_sec = st.st_atime;
    }

    /* Wait until the atime on the last file is actually in the past. */
    sleepUntilAfter(files[numfiles - 1].atime_sec);
}

DEFINE_TEST(test_option_a)
{
    struct stat st;
    int r;
    char *p;

    /* Create all of the test files. */
    test_create();

    /* Sanity check; verify that atimes really do get modified. */
    assert((p = slurpfile(NULL, "f0")) != NULL);
    free(p);
    assertEqualInt(0, stat("f0", &st));
    if (st.st_atime == files[0].atime_sec) {
        skipping("Cannot verify -a option\n"
            "      Your system appears to not support atime.");
    }
    else
    {
        /*
         * If this disk is mounted noatime, then we can't
         * verify correct operation without -a.
         */

        /* Copy the file without -a; should change the atime. */
        r = systemf("echo %s | %s -pd copy-no-a > copy-no-a.out 2>copy-no-a.err", files[1].name, testprog);
        assertEqualInt(r, 0);
        assertTextFileContents("1 block\n", "copy-no-a.err");
        assertEmptyFile("copy-no-a.out");
        assertEqualInt(0, stat(files[1].name, &st));
        failure("Copying file without -a should have changed atime.");
        assert(st.st_atime != files[1].atime_sec);

        /* Archive the file without -a; should change the atime. */
        r = systemf("echo %s | %s -o > archive-no-a.out 2>archive-no-a.err", files[2].name, testprog);
        assertEqualInt(r, 0);
        assertTextFileContents("1 block\n", "copy-no-a.err");
        assertEqualInt(0, stat(files[2].name, &st));
        failure("Archiving file without -a should have changed atime.");
        assert(st.st_atime != files[2].atime_sec);
    }

    /*
     * We can, of course, still verify that the atime is unchanged
     * when using the -a option.
     */

    /* Copy the file with -a; should not change the atime. */
    r = systemf("echo %s | %s -pad copy-a > copy-a.out 2>copy-a.err",
        files[3].name, testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "copy-a.err");
    assertEmptyFile("copy-a.out");
    assertEqualInt(0, stat(files[3].name, &st));
    failure("Copying file with -a should not have changed atime.");
    assertEqualInt(st.st_atime, files[3].atime_sec);

    /* Archive the file with -a; should not change the atime. */
    r = systemf("echo %s | %s -oa > archive-a.out 2>archive-a.err",
        files[4].name, testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "copy-a.err");
    assertEqualInt(0, stat(files[4].name, &st));
    failure("Archiving file with -a should not have changed atime.");
    assertEqualInt(st.st_atime, files[4].atime_sec);
}

--- NEW FILE: test_option_C_upper.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");


DEFINE_TEST(test_option_C_upper)
{
    int r;

    /*
     * Create a file on disk.
     */
    assertMakeFile("file", 0644, NULL);

    /* Create an archive without -C; this should be 512 bytes. */
    r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "small.err");
    assertFileSize("small.cpio", 512);

    /* Create an archive with -C 513; this should be 513 bytes. */
    r = systemf("echo file | %s -o -C 513 > 513.cpio 2>513.err",
            testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "513.err");
    assertFileSize("513.cpio", 513);

    /* Create an archive with -C 12345; this should be 12345 bytes. */
    r = systemf("echo file | %s -o -C12345 > 12345.cpio 2>12345.err",
            testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "12345.err");
    assertFileSize("12345.cpio", 12345);

    /* Create an archive with invalid -C request */
    assert(0 != systemf("echo file | %s -o -C > bad.cpio 2>bad.err",
                testprog));
    assertEmptyFile("bad.cpio");
}

--- NEW FILE: test_cmdline.c ---
/*-
 * Copyright (c) 2003-2009 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

/*
 * Test the command-line parsing.
 */

DEFINE_TEST(test_cmdline)
{
    FILE *f;

    /* Create an empty file. */
    f = fopen("empty", "wb");
    assert(f != NULL);
    fclose(f);

    failure("-Q is an invalid option on every cpio program I know of");
    assert(0 != systemf("%s -i -Q <empty >1.out 2>1.err", testprog));
    assertEmptyFile("1.out");

    failure("-f requires an argument");
    assert(0 != systemf("%s -if <empty >2.out 2>2.err", testprog));
    assertEmptyFile("2.out");

    failure("-f requires an argument");
    assert(0 != systemf("%s -i -f <empty >3.out 2>3.err", testprog));
    assertEmptyFile("3.out");

    failure("--format requires an argument");
    assert(0 != systemf("%s -i --format <empty >4.out 2>4.err", testprog));
    assertEmptyFile("4.out");

    failure("--badopt is an invalid option");
    assert(0 != systemf("%s -i --badop <empty >5.out 2>5.err", testprog));
    assertEmptyFile("5.out");

    failure("--badopt is an invalid option");
    assert(0 != systemf("%s -i --badopt <empty >6.out 2>6.err", testprog));
    assertEmptyFile("6.out");

    failure("--n is ambiguous");
    assert(0 != systemf("%s -i --n <empty >7.out 2>7.err", testprog));
    assertEmptyFile("7.out");

    failure("--create forbids an argument");
    assert(0 != systemf("%s --create=arg <empty >8.out 2>8.err", testprog));
    assertEmptyFile("8.out");

    failure("-i with empty input should succeed");
    assert(0 == systemf("%s -i <empty >9.out 2>9.err", testprog));
    assertEmptyFile("9.out");

    failure("-o with empty input should succeed");
    assert(0 == systemf("%s -o <empty >10.out 2>10.err", testprog));

    failure("-i -p is nonsense");
    assert(0 != systemf("%s -i -p <empty >11.out 2>11.err", testprog));
    assertEmptyFile("11.out");

    failure("-p -i is nonsense");
    assert(0 != systemf("%s -p -i <empty >12.out 2>12.err", testprog));
    assertEmptyFile("12.out");

    failure("-i -o is nonsense");
    assert(0 != systemf("%s -i -o <empty >13.out 2>13.err", testprog));
    assertEmptyFile("13.out");

    failure("-o -i is nonsense");
    assert(0 != systemf("%s -o -i <empty >14.out 2>14.err", testprog));
    assertEmptyFile("14.out");

    failure("-o -p is nonsense");
    assert(0 != systemf("%s -o -p <empty >15.out 2>15.err", testprog));
    assertEmptyFile("15.out");

    failure("-p -o is nonsense");
    assert(0 != systemf("%s -p -o <empty >16.out 2>16.err", testprog));
    assertEmptyFile("16.out");

    failure("-p with empty input should fail");
    assert(0 != systemf("%s -p <empty >17.out 2>17.err", testprog));
    assertEmptyFile("17.out");
}

--- NEW FILE: test_option_y.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_option_y.c,v 1.2 2008/08/24 06:21:00 kientzle Exp $");

DEFINE_TEST(test_option_y)
{
    char *p;
    int r;
    size_t s;

    /* Create a file. */
    assertMakeFile("f", 0644, "a");

    /* Archive it with bzip2 compression. */
    r = systemf("echo f | %s -oy >archive.out 2>archive.err",
        testprog);
    p = slurpfile(&s, "archive.err");
    p[s] = '\0';
    if (r != 0) {
        if (strstr(p, "compression not available") != NULL) {
            skipping("This version of bsdcpio was compiled "
                "without bzip2 support");
            return;
        }
        failure("-y option is broken");
        assertEqualInt(r, 0);
        return;
    }
    assertTextFileContents("1 block\n", "archive.err");
    /* Check that the archive file has a bzip2 signature. */
    p = slurpfile(&s, "archive.out");
    assert(s > 2);
    assertEqualMem(p, "BZh9", 4);
}

--- NEW FILE: Makefile ---
# $FreeBSD: src/usr.bin/cpio/test/Makefile,v 1.4 2008/08/24 05:49:36 kientzle Exp $

# Where to find the cpio sources (for the internal unit tests)
CPIO_SRCDIR=${.CURDIR}/..
.PATH: ${CPIO_SRCDIR} ${CPIO_SRCDIR}/../libarchive_fe

# Some cpio sources are pulled in for white-box tests
CPIO_SRCS= cmdline.c err.c pathmatch.c

TESTS=  \
    test_0.c                \
    test_basic.c                \
    test_cmdline.c              \
    test_format_newc.c          \
    test_gcpio_compat.c         \
    test_option_B_upper.c           \
    test_option_C_upper.c           \
    test_option_J_upper.c           \
    test_option_L_upper.c           \
    test_option_Z_upper.c           \
    test_option_a.c             \
    test_option_c.c             \
    test_option_d.c             \
    test_option_f.c             \
    test_option_help.c          \
    test_option_l.c             \
    test_option_lzma.c          \
    test_option_m.c             \
    test_option_t.c             \
    test_option_u.c             \
    test_option_version.c           \
    test_option_y.c             \
    test_option_z.c             \
    test_owner_parse.c          \
    test_passthrough_dotdot.c       \
    test_passthrough_reverse.c      \
    test_pathmatch.c

# Build the test program
SRCS= list.h                    \
    ${CPIO_SRCS}                \
    ${TESTS}                \
    main.c

CLEANFILES+= list.h bsdcpio_test

NO_MAN=yes

PROG=bsdcpio_test
DPADD=${LIBARCHIVE} ${LIBBZ2} ${LIBZ}
CFLAGS+=    -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
CFLAGS+=    -I.. -I../../libarchive_fe
LDADD= -larchive -lz -lbz2
CFLAGS+= -static -g -O2 -Wall
CFLAGS+= -I${.OBJDIR}
CFLAGS+= -I${CPIO_SRCDIR}

# Uncomment to link against dmalloc
#LDADD+= -L/usr/local/lib -ldmalloc
#CFLAGS+= -I/usr/local/include -DUSE_DMALLOC
WARNS=6

check test: bsdcpio_test
    ${.OBJDIR}/bsdcpio_test -p ${.OBJDIR}/../bsdcpio -r ${.CURDIR}

${.OBJDIR}/list.h list.h: ${TESTS} Makefile
    (cd ${.CURDIR}; cat ${TESTS}) | grep DEFINE_TEST > list.h

clean:
    rm -f ${CLEANFILES}
    rm -f *~
    -chmod -R +w /tmp/bsdcpio_test.*
    rm -rf /tmp/bsdcpio_test.*

.include <bsd.prog.mk>

--- NEW FILE: test_option_t.stdout.uu ---
$FreeBSD$
begin 644 test_option_t.stdout
%9FEL90H`
`
end

--- NEW FILE: test_passthrough_dotdot.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_passthrough_dotdot.c,v 1.4 2008/08/24 06:21:00 kientzle Exp $");

/*
 * Verify that "cpio -p .." works.
 */

DEFINE_TEST(test_passthrough_dotdot)
{
    int r;
    FILE *filelist;

    assertUmask(0);

    /*
     * Create an assortment of files on disk.
     */
    filelist = fopen("filelist", "w");

    /* Directory. */
    assertMakeDir("dir", 0755);
    assertChdir("dir");

    fprintf(filelist, ".\n");

    /* File with 10 bytes content. */
    assertMakeFile("file", 0642, "1234567890");
    fprintf(filelist, "file\n");

    /* All done. */
    fclose(filelist);


    /*
     * Use cpio passthrough mode to copy files to another directory.
     */
    r = systemf("%s -pdvm .. <../filelist >../stdout 2>../stderr",
        testprog);
    failure("Error invoking %s -pd ..", testprog);
    assertEqualInt(r, 0);

    assertChdir("..");

    /* Verify stderr and stdout. */
    assertTextFileContents("../.\n../file\n1 block\n", "stderr");
    assertEmptyFile("stdout");

    /* Regular file. */
    assertIsReg("file", 0642);
    assertFileSize("file", 10);
    assertFileNLinks("file", 1);
}

--- NEW FILE: test_option_f.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

/*
 * Unpack the archive in a new dir.
 */
static void
unpack(const char *dirname, const char *option)
{
    int r;

    assertMakeDir(dirname, 0755);
    assertChdir(dirname);
    extract_reference_file("test_option_f.cpio");
    r = systemf("%s -i %s < test_option_f.cpio > copy-no-a.out 2>copy-no-a.err", testprog, option);
    assertEqualInt(0, r);
    assertChdir("..");
}

DEFINE_TEST(test_option_f)
{
    /* Calibrate:  No -f option, so everything should be extracted. */
    unpack("t0", "--no-preserve-owner");
    assertFileExists("t0/a123");
    assertFileExists("t0/a234");
    assertFileExists("t0/b123");
    assertFileExists("t0/b234");

    /* Don't extract 'a*' files. */
#if defined(_WIN32) && !defined(__CYGWIN__)
    /* Single quotes isn't used by command.exe. */
    unpack("t1", "--no-preserve-owner -f a*");
#else
    unpack("t1", "--no-preserve-owner -f 'a*'");
#endif
    assertFileNotExists("t1/a123");
    assertFileNotExists("t1/a234");
    assertFileExists("t1/b123");
    assertFileExists("t1/b234");

    /* Don't extract 'b*' files. */
#if defined(_WIN32) && !defined(__CYGWIN__)
    /* Single quotes isn't used by command.exe. */
    unpack("t2", "--no-preserve-owner -f b*");
#else
    unpack("t2", "--no-preserve-owner -f 'b*'");
#endif
    assertFileExists("t2/a123");
    assertFileExists("t2/a234");
    assertFileNotExists("t2/b123");
    assertFileNotExists("t2/b234");
}

--- NEW FILE: CMakeLists.txt ---
############################################
#
# How to build bsdcpio_test
#
############################################
IF(ENABLE_CPIO AND ENABLE_TEST)
  SET(bsdcpio_test_SOURCES
    ../cmdline.c
    ../../libarchive_fe/err.c
    ../../libarchive_fe/pathmatch.c
    main.c
    test.h
    test_0.c
    test_basic.c
    test_cmdline.c
    test_format_newc.c
    test_gcpio_compat.c
    test_option_B_upper.c
    test_option_C_upper.c
    test_option_J_upper.c
    test_option_L_upper.c
    test_option_Z_upper.c
    test_option_a.c
    test_option_c.c
    test_option_d.c
    test_option_f.c
    test_option_help.c
    test_option_l.c
    test_option_lzma.c
    test_option_m.c
    test_option_t.c
    test_option_u.c
    test_option_version.c
    test_option_y.c
    test_option_z.c
    test_owner_parse.c
    test_passthrough_dotdot.c
    test_passthrough_reverse.c
    test_pathmatch.c
  )
  IF(WIN32 AND NOT CYGWIN)
    LIST(APPEND bsdcpio_test_SOURCES ../cpio_windows.h)
  ENDIF(WIN32 AND NOT CYGWIN)

  #
  # Generate the list.h
  #
  GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h
    ${CMAKE_CURRENT_LIST_FILE} ${bsdcpio_test_SOURCES})
  SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
    ${CMAKE_CURRENT_BINARY_DIR})
  #
  # Register target
  #
  ADD_EXECUTABLE(bsdcpio_test ${bsdcpio_test_SOURCES})
  SET_PROPERTY(TARGET bsdcpio_test PROPERTY COMPILE_DEFINITIONS LIST_H)

  # ADD_TEST() for each separate test
  SET(num 0)
  FOREACH(test ${bsdcpio_test_SOURCES})
    IF(test MATCHES "^test_[^/]+[.]c$")
      STRING(REGEX REPLACE "^(test_[^/]+)[.]c$" "\\1" testname ${test})
      ADD_TEST("bsdcpio_${testname}" bsdcpio_test
        -v -p ${BSDCPIO} -r ${CMAKE_CURRENT_SOURCE_DIR} ${num})
      MATH(EXPR num "${num} + 1")
    ENDIF(test MATCHES "^test_[^/]+[.]c$")
  ENDFOREACH(test)

  # Experimental new test handling
  ADD_CUSTOM_TARGET(run_bsdcpio_test
    COMMAND bsdcpio_test -p ${BSDCPIO} -r ${CMAKE_CURRENT_SOURCE_DIR})
  ADD_DEPENDENCIES(run_bsdcpio_test bsdcpio)
  ADD_DEPENDENCIES(run_all_tests run_bsdcpio_test)
ENDIF(ENABLE_CPIO AND ENABLE_TEST)


--- NEW FILE: test_gcpio_compat_ref_nosym.ustar.uu ---
begin 644 test_gcpio_compat_ref_nosym.ustar
M9&ER+P``````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````#`P,#`W-S4`,#`P,3<U,``P,#`Q-S4P`#`P,#`P,#`P,#`P
M`#$Q,C4S,C$W,C<S`#`P,3$S-3$`-0``````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````!U<W1A<@`P,'1I;0``
M````````````````````````````````````=&EM````````````````````
M```````````````````P,#`P,C<S`#8V,#`P-C8`````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````!F:6QE````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````,#`P,#8T-``P,#`Q-S4P`#`P
M,#$W-3``,#`P,#`P,#`P,3(`,3$R-3,R,3<R-S,`,#`Q,30R,P`P````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````'5S=&%R`#`P=&EM``````````````````````````````````````!T
M:6T``````````````````````````````````````#`P,#`R-S,`-C8P,#`T
M-P``````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````````````````````````````#$R,S0U-C<X.0H`
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````;&EN:V9I;&4`````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````#`P,#`V-#0`,#`P,3<U,``P,#`Q-S4P`#`P,#`P
M,#`P,#`P`#$Q,C4S,C$W,C<S`#`P,3,Q,S<`,69I;&4`````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````````````!U<W1A<@`P
M,'1I;0``````````````````````````````````````=&EM````````````
M```````````````````````````P,#`P,C<S`#8V,#`P-#<`````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
,````````````````
`
end

--- NEW FILE: test_option_L_upper.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_option_L.c,v 1.2 2008/08/24 06:21:00 kientzle Exp $");

/* This is a little pointless, as Windows doesn't support symlinks
 * (except for the seriously crippled CreateSymbolicLink API) so these
 * tests won't run on Windows. */
#if defined(_WIN32) && !defined(__CYGWIN__)
#define CAT "type"
#else
#define CAT "cat"
#endif

DEFINE_TEST(test_option_L_upper)
{
    FILE *filelist;
    int r;

    if (!canSymlink()) {
        skipping("Symlink tests");
        return;
    }

    filelist = fopen("filelist", "w");

    /* Create a file and a symlink to the file. */
    assertMakeFile("file", 0644, "1234567890");
    fprintf(filelist, "file\n");

    /* Symlink to above file. */
    assertMakeSymlink("symlink", "file");
    fprintf(filelist, "symlink\n");

    fclose(filelist);

    r = systemf(CAT " filelist | %s -pd copy >copy.out 2>copy.err", testprog);
    assertEqualInt(r, 0);

    failure("Regular -p without -L should preserve symlinks.");
    assertIsSymlink("copy/symlink", NULL);

    r = systemf(CAT " filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog);
    assertEqualInt(r, 0);
    assertEmptyFile("copy-L.out");
    assertTextFileContents("1 block\n", "copy-L.err");
    failure("-pdL should dereference symlinks and turn them into files.");
    assertIsReg("copy-L/symlink", -1);

    r = systemf(CAT " filelist | %s -o >archive.out 2>archive.err", testprog);
    failure("Error invoking %s -o ", testprog);
    assertEqualInt(r, 0);

    assertMakeDir("unpack", 0755);
    assertChdir("unpack");
    r = systemf(CAT " ../archive.out | %s -i >unpack.out 2>unpack.err", testprog);
    assertChdir("..");
    failure("Error invoking %s -i", testprog);
    assertEqualInt(r, 0);

    assertIsSymlink("unpack/symlink", NULL);

    r = systemf(CAT " filelist | %s -oL >archive-L.out 2>archive-L.err", testprog);
    failure("Error invoking %s -oL", testprog);
    assertEqualInt(r, 0);

    assertMakeDir("unpack-L", 0755);
    assertChdir("unpack-L");
    r = systemf(CAT " ../archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog);
    assertChdir("..");
    failure("Error invoking %s -i < archive-L.out", testprog);
    assertEqualInt(r, 0);
    assertIsReg("unpack-L/symlink", -1);
}

--- NEW FILE: test_option_tv.stdout.uu ---
$FreeBSD: src/usr.bin/cpio/test/test_option_tv.stdout.uu,v 1.2 2008/11/29 20:22:02 kientzle Exp $
begin 644 test_option_tv.stdout
M+7)W+7(M+7(M+2`@(#$@=&EM("`@("`@=&EM("`@("`@("`@("`@(#`@1&5C
/(#,Q("`Q.38Y(&9I;&4*
`
end

--- NEW FILE: test.h ---
/*
 * Copyright (c) 2003-2006 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD: src/usr.bin/cpio/test/test.h,v 1.2 2008/06/21 02:17:18 kientzle Exp $
 */

/* Every test program should #include "test.h" as the first thing. */

/*
 * The goal of this file (and the matching test.c) is to
 * simplify the very repetitive test-*.c test programs.
 */
#if defined(HAVE_CONFIG_H)
/* Most POSIX platforms use the 'configure' script to build config.h */
#include "config.h"
#elif defined(__FreeBSD__)
/* Building as part of FreeBSD system requires a pre-built config.h. */
#include "config_freebsd.h"
#elif defined(_WIN32) && !defined(__CYGWIN__)
/* Win32 can't run the 'configure' script. */
#include "config_windows.h"
#else
/* Warn if the library hasn't been (automatically or manually) configured. */
#error Oops: No config.h and no pre-built configuration in test.h.
#endif

#include <sys/types.h>  /* Windows requires this before sys/stat.h */
#include <sys/stat.h>

#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#if HAVE_DIRENT_H
#include <dirent.h>
#else
#include <direct.h>
#define dirent direct
#endif
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_IO_H
#include <io.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <wchar.h>
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif

/*
 * System-specific tweaks.  We really want to minimize these
 * as much as possible, since they make it harder to understand
 * the mainline code.
 */

/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "../cpio_windows.h"
#define strdup _strdup
#define LOCALE_DE   "deu"
#else
#define LOCALE_DE   "de_DE.UTF-8"
#endif

/* Visual Studio */
#ifdef _MSC_VER
#define snprintf    sprintf_s
#endif

/* Cygwin */
#if defined(__CYGWIN__)
/* Cygwin-1.7.x is lazy about populating nlinks, so don't
 * expect it to be accurate. */
# define NLINKS_INACCURATE_FOR_DIRS
#endif

/* FreeBSD */
#ifdef __FreeBSD__
#include <sys/cdefs.h>  /* For __FBSDID */
#else
/* Surprisingly, some non-FreeBSD platforms define __FBSDID. */
#ifndef __FBSDID
#define __FBSDID(a)     struct _undefined_hack
#endif
#endif

#ifndef O_BINARY
#define O_BINARY 0
#endif

/*
 * Redefine DEFINE_TEST for use in defining the test functions.
 */
#undef DEFINE_TEST
#define DEFINE_TEST(name) void name(void); void name(void)

/* An implementation of the standard assert() macro */
#define assert(e)   assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
/* chdir() and error if it fails */
#define assertChdir(path)  \
  assertion_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same.  Reports value of each one if not. */
#define assertEqualInt(v1,v2) \
  assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same.  Reports value of each one if not. */
#define assertEqualString(v1,v2)   \
  assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2)   \
  assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l)   \
  assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert two files are the same; allow printf-style expansion of second name.
 * See below for comments about variable arguments here...
 */
#define assertEqualFile     \
  assertion_setup(__FILE__, __LINE__);assertion_equal_file
/* Assert that a file is empty; supports printf-style arguments. */
#define assertEmptyFile     \
  assertion_setup(__FILE__, __LINE__);assertion_empty_file
/* Assert that a file is not empty; supports printf-style arguments. */
#define assertNonEmptyFile      \
  assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
#define assertFileAtime(pathname, sec, nsec)    \
  assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
  assertion_file_atime_recent(__FILE__, __LINE__, pathname)
#define assertFileBirthtime(pathname, sec, nsec)    \
  assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileBirthtimeRecent(pathname) \
  assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists        \
  assertion_setup(__FILE__, __LINE__);assertion_file_exists
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileNotExists     \
  assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
/* Assert that file contents match a string; supports printf-style arguments. */
#define assertFileContents             \
  assertion_setup(__FILE__, __LINE__);assertion_file_contents
#define assertFileMtime(pathname, sec, nsec)    \
  assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
  assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
#define assertFileNLinks(pathname, nlinks)  \
  assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size)  \
  assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertTextFileContents         \
  assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
#define assertIsDir(pathname, mode)     \
  assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2)  \
  assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsNotHardlink(path1, path2)   \
  assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsReg(pathname, mode)     \
  assertion_is_reg(__FILE__, __LINE__, pathname, mode)
#define assertIsSymlink(pathname, contents) \
  assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
/* Create a directory, report error if it fails. */
#define assertMakeDir(dirname, mode)    \
  assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
  assertion_make_file(__FILE__, __LINE__, path, mode, contents)
#define assertMakeHardlink(newfile, oldfile)    \
  assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto)  \
  assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertUmask(mask)   \
  assertion_umask(__FILE__, __LINE__, mask)

/*
 * This would be simple with C99 variadic macros, but I don't want to
 * require that.  Instead, I insert a function call before each
 * skipping() call to pass the file and line information down.  Crude,
 * but effective.
 */
#define skipping    \
  assertion_setup(__FILE__, __LINE__);test_skipping

/* Function declarations.  These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
int assertion_empty_file(const char *, ...);
int assertion_equal_file(const char *, const char *, ...);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contents(const void *, int, const char *, ...);
int assertion_file_exists(const char *, ...);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
int assertion_file_not_exists(const char *, ...);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, const char *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_non_empty_file(const char *, ...);
int assertion_text_file_contents(const char *buff, const char *f);
int assertion_umask(const char *, int, int);
void assertion_setup(const char *, int);

void test_skipping(const char *fmt, ...);

/* Like sprintf, then system() */
int systemf(const char * fmt, ...);

/* Delay until time() returns a value after this. */
void sleepUntilAfter(time_t);

/* Return true if this platform can create symlinks. */
int canSymlink(void);

/* Return true if this platform can run the "gzip" program. */
int canGzip(void);

/* Return true if this platform can run the "gunzip" program. */
int canGunzip(void);

/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);

/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);

/*
 * Special interfaces for program test harness.
 */

/* Pathname of exe to be tested. */
const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
const char *testprog;

--- NEW FILE: test_option_J_upper.c ---
/*-
 * Copyright (c) 2003-2009 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

DEFINE_TEST(test_option_J_upper)
{
    char *p;
    int r;
    size_t s;

    /* Create a file. */
    assertMakeFile("f", 0644, "a");

    /* Archive it with xz compression. */
    r = systemf("echo f | %s -o -J >archive.out 2>archive.err",
        testprog);
    p = slurpfile(&s, "archive.err");
    p[s] = '\0';
    if (r != 0) {
        if (strstr(p, "compression not available") != NULL) {
            skipping("This version of bsdcpio was compiled "
                "without xz support");
            return;
        }
        failure("-J option is broken");
        assertEqualInt(r, 0);
        return;
    }
    /* Check that the archive file has an xz signature. */
    p = slurpfile(&s, "archive.out");
    assert(s > 2);
    assertEqualMem(p, "\3757zXZ", 5);
}

--- NEW FILE: test_gcpio_compat_ref_nosym.bin.uu ---
begin 644 test_gcpio_compat_ref_nosym.bin
MQW%4`-[Z_4'H`^@#`@`VNZU*NQX$``````!D:7(`QW%4`-SZI('H`^@#`@`G
MNZU*NQX%````"@!F:6QE```Q,C,T-38W.#D*QW%4`-SZI('H`^@#`@`GNZU*
MNQX)````"@!L:6YK9FEL90``,3(S-#4V-S at Y"L=Q``````````````$`````
M````"P``````5%)!24Q%4B$A(0``````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
1````````````````````````
`
end

--- NEW FILE: main.c ---
/*
 * Copyright (c) 2003-2009 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
[...2020 lines suppressed...]
                    tests[i].name, tests[i].failures);
        }
        printf("\n");
        printf("Details for failing tests: %s\n", tmpdir);
        printf("\n");
    } else {
        if (verbosity == VERBOSITY_SUMMARY_ONLY)
            printf("\n");
        printf("%d tests passed, no failures\n", tests_run);
    }

    free(refdir_alloc);

    /* If the final tmpdir is empty, we can remove it. */
    /* This should be the usual case when all tests succeed. */
    assertChdir("..");
    rmdir(tmpdir);

    return (tests_failed ? 1 : 0);
}

--- NEW FILE: test_option_B_upper.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");


DEFINE_TEST(test_option_B_upper)
{
    struct stat st;
    int r;

    /*
     * Create a file on disk.
     */
    assertMakeFile("file", 0644, NULL);

    /* Create an archive without -B; this should be 512 bytes. */
    r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "small.err");
    assertEqualInt(0, stat("small.cpio", &st));
    assertEqualInt(512, st.st_size);

    /* Create an archive with -B; this should be 5120 bytes. */
    r = systemf("echo file | %s -oB > large.cpio 2>large.err", testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "large.err");
    assertEqualInt(0, stat("large.cpio", &st));
    assertEqualInt(5120, st.st_size);
}

--- NEW FILE: test_option_m.cpio.uu ---
$FreeBSD$
begin 644 test_option_m.cpio
M,#<P-S`W,#`P,3,Q-#4P,#8T,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P
M,#`P,#`P,#`P,#`P,#$P,#`P,#4P,#`P,#`P,#`P,&9I;&4`,#<P-S`W,#`P
M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P,#`P,#`P
M,#`P,#`P,#`P,3,P,#`P,#`P,#`P,%1204E,15(A(2$`````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
1````````````````````````
`
end

--- NEW FILE: test_option_z.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

DEFINE_TEST(test_option_z)
{
    char *p;
    int r;
    size_t s;

    /* Create a file. */
    assertMakeFile("f", 0644, "a");

    /* Archive it with gzip compression. */
    r = systemf("echo f | %s -oz >archive.out 2>archive.err",
        testprog);
    p = slurpfile(&s, "archive.err");
    p[s] = '\0';
    if (r != 0) {
        if (strstr(p, "compression not available") != NULL) {
            skipping("This version of bsdcpio was compiled "
                "without gzip support");
            return;
        }
        failure("-z option is broken");
        assertEqualInt(r, 0);
        return;
    }
    /* Check that the archive file has a gzip signature. */
    p = slurpfile(&s, "archive.out");
    assert(s > 4);
    assertEqualMem(p, "\x1f\x8b\x08\x00", 4);
}

--- NEW FILE: test_option_c.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

static int
is_octal(const char *p, size_t l)
{
    while (l > 0) {
        if (*p < '0' || *p > '7')
            return (0);
        --l;
        ++p;
    }
    return (1);
}

static int
from_octal(const char *p, size_t l)
{
    int r = 0;

    while (l > 0) {
        r *= 8;
        r += *p - '0';
        --l;
        ++p;
    }
    return (r);
}

DEFINE_TEST(test_option_c)
{
    FILE *filelist;
    int r;
    int uid = -1;
    int dev, ino, gid;
    time_t t, now;
    char *p, *e;
    size_t s;

    assertUmask(0);

#if !defined(_WIN32)
    uid = getuid();
#endif

    /*
     * Create an assortment of files.
     * TODO: Extend this to cover more filetypes.
     */
    filelist = fopen("filelist", "w");

    /* "file" */
    assertMakeFile("file", 0644, "1234567890");
    fprintf(filelist, "file\n");

    /* "symlink" */
    if (canSymlink()) {
        assertMakeSymlink("symlink", "file");
        fprintf(filelist, "symlink\n");
    }

    /* "dir" */
    assertMakeDir("dir", 0775);
    /* Record some facts about what we just created: */
    now = time(NULL); /* They were all created w/in last two seconds. */
    fprintf(filelist, "dir\n");

    /* Use the cpio program to create an archive. */
    fclose(filelist);
    r = systemf("%s -oc <filelist >basic.out 2>basic.err", testprog);
    /* Verify that nothing went to stderr. */
    assertTextFileContents("1 block\n", "basic.err");

    /* Assert that the program finished. */
    failure("%s -oc crashed", testprog);
    if (!assertEqualInt(r, 0))
        return;

    /* Verify that stdout is a well-formed cpio file in "odc" format. */
    p = slurpfile(&s, "basic.out");
    assertEqualInt(s, 512);
    e = p;

    /*
     * Some of these assertions could be stronger, but it's
     * a little tricky because they depend on the local environment.
     */

    /* First entry is "file" */
    assert(is_octal(e, 76)); /* Entire header is octal digits. */
    assertEqualMem(e + 0, "070707", 6); /* Magic */
    assert(is_octal(e + 6, 6)); /* dev */
    dev = from_octal(e + 6, 6);
    assert(is_octal(e + 12, 6)); /* ino */
    ino = from_octal(e + 12, 6);
#if defined(_WIN32) && !defined(__CYGWIN__)
    /* Group members bits and others bits do not work. */
    assertEqualMem(e + 18, "100666", 6); /* Mode */
#else
    assertEqualMem(e + 18, "100644", 6); /* Mode */
#endif
    if (uid < 0)
        uid = from_octal(e + 24, 6);
    assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
    assert(is_octal(e + 30, 6)); /* gid */
    gid = from_octal(e + 30, 6);
    assertEqualMem(e + 36, "000001", 6); /* nlink */
    failure("file entries should not have rdev set (dev field was 0%o)",
        dev);
    assertEqualMem(e + 42, "000000", 6); /* rdev */
    t = from_octal(e + 48, 11); /* mtime */
    assert(t <= now); /* File wasn't created in future. */
    assert(t >= now - 2); /* File was created w/in last 2 secs. */
    assertEqualMem(e + 59, "000005", 6); /* Name size */
    assertEqualMem(e + 65, "00000000012", 11); /* File size */
    assertEqualMem(e + 76, "file\0", 5); /* Name contents */
    assertEqualMem(e + 81, "1234567890", 10); /* File contents */
    e += 91;

    /* "symlink" pointing to "file" */
    if (canSymlink()) {
        assert(is_octal(e, 76)); /* Entire header is octal digits. */
        assertEqualMem(e + 0, "070707", 6); /* Magic */
        assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */
        assert(dev != from_octal(e + 12, 6)); /* ino */
#if !defined(_WIN32) || defined(__CYGWIN__)
        /* On Windows, symbolic link and group members bits and
         * others bits do not work. */
        assertEqualMem(e + 18, "120777", 6); /* Mode */
#endif
        assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
        assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */
        assertEqualMem(e + 36, "000001", 6); /* nlink */
        failure("file entries should have rdev == 0 (dev was 0%o)",
            from_octal(e + 6, 6));
        assertEqualMem(e + 42, "000000", 6); /* rdev */
        t = from_octal(e + 48, 11); /* mtime */
        assert(t <= now); /* File wasn't created in future. */
        assert(t >= now - 2); /* File was created w/in last 2 secs. */
        assertEqualMem(e + 59, "000010", 6); /* Name size */
        assertEqualMem(e + 65, "00000000004", 11); /* File size */
        assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */
        assertEqualMem(e + 84, "file", 4); /* Symlink target. */
        e += 88;
    }

    /* "dir" */
    assert(is_octal(e, 76));
    assertEqualMem(e + 0, "070707", 6); /* Magic */
    /* Dev should be same as first entry. */
    assert(is_octal(e + 6, 6)); /* dev */
    assertEqualInt(dev, from_octal(e + 6, 6));
    /* Ino must be different from first entry. */
    assert(is_octal(e + 12, 6)); /* ino */
    assert(dev != from_octal(e + 12, 6));
#if defined(_WIN32) && !defined(__CYGWIN__)
    /* Group members bits and others bits do not work. */
    assertEqualMem(e + 18, "040777", 6); /* Mode */
#else
    /* Accept 042775 to accomodate systems where sgid bit propagates. */
    if (memcmp(e + 18, "042775", 6) != 0)
        assertEqualMem(e + 18, "040775", 6); /* Mode */
#endif
    assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
    /* Gid should be same as first entry. */
    assert(is_octal(e + 30, 6)); /* gid */
    assertEqualInt(gid, from_octal(e + 30, 6));
#ifndef NLINKS_INACCURATE_FOR_DIRS
    assertEqualMem(e + 36, "000002", 6); /* Nlink */
#endif
    t = from_octal(e + 48, 11); /* mtime */
    assert(t <= now); /* File wasn't created in future. */
    assert(t >= now - 2); /* File was created w/in last 2 secs. */
    assertEqualMem(e + 59, "000004", 6); /* Name size */
    assertEqualMem(e + 65, "00000000000", 11); /* File size */
    assertEqualMem(e + 76, "dir\0", 4); /* name */
    e += 80;

    /* TODO: Verify other types of entries. */

    /* Last entry is end-of-archive marker. */
    assert(is_octal(e, 76));
    assertEqualMem(e + 0, "070707", 6); /* Magic */
    assertEqualMem(e + 6, "000000", 6); /* dev */
    assertEqualMem(e + 12, "000000", 6); /* ino */
    assertEqualMem(e + 18, "000000", 6); /* Mode */
    assertEqualMem(e + 24, "000000", 6); /* uid */
    assertEqualMem(e + 30, "000000", 6); /* gid */
    assertEqualMem(e + 36, "000001", 6); /* Nlink */
    assertEqualMem(e + 42, "000000", 6); /* rdev */
    assertEqualMem(e + 48, "00000000000", 11); /* mtime */
    assertEqualMem(e + 59, "000013", 6); /* Name size */
    assertEqualMem(e + 65, "00000000000", 11); /* File size */
    assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */

    free(p);
}

--- NEW FILE: test_passthrough_reverse.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_passthrough_reverse.c,v 1.2 2008/08/24 06:21:00 kientzle Exp $");

/*
 * As reported by Bernd Walter:  Some people are in the habit of
 * using "find -d" to generate a list for cpio -p because that
 * copies the top-level dir last, which preserves owner and mode
 * information.  That's not necessary for bsdcpio (libarchive defers
 * restoring directory information), but bsdcpio should still generate
 * the correct results with this usage.
 */

DEFINE_TEST(test_passthrough_reverse)
{
    int r;
    FILE *filelist;

    assertUmask(0);

    /*
     * Create an assortment of files on disk.
     */
    filelist = fopen("filelist", "w");

    /* Directory. */
    assertMakeDir("dir", 0743);

    /* File with 10 bytes content. */
    assertMakeFile("dir/file", 0644, "1234567890");
    fprintf(filelist, "dir/file\n");

    /* Write dir last. */
    fprintf(filelist, "dir\n");

    /* All done. */
    fclose(filelist);


    /*
     * Use cpio passthrough mode to copy files to another directory.
     */
    r = systemf("%s -pdvm out <filelist >stdout 2>stderr", testprog);
    failure("Error invoking %s -pd out", testprog);
    assertEqualInt(r, 0);

    assertChdir("out");

    /* Verify stderr and stdout. */
    assertTextFileContents("out/dir/file\nout/dir\n1 block\n",
        "../stderr");
    assertEmptyFile("../stdout");

    /* dir */
    assertIsDir("dir", 0743);


    /* Regular file. */
    assertIsReg("dir/file", 0644);
    assertFileSize("dir/file", 10);
    assertFileNLinks("dir/file", 1);
}

--- NEW FILE: test_option_help.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

/*
 * Test that "--help", "-h", and "-W help" options all work and
 * generate reasonable output.
 */

static int
in_first_line(const char *p, const char *substring)
{
    size_t l = strlen(substring);

    while (*p != '\0' && *p != '\n') {
        if (memcmp(p, substring, l) == 0)
            return (1);
        ++p;
    }
    return (0);
}

DEFINE_TEST(test_option_help)
{
    int r;
    char *p;
    size_t plen;

    /* Exercise --help option. */
    r = systemf("%s --help >help.stdout 2>help.stderr", testprog);
    failure("--help should generate nothing to stderr.");
    assertEmptyFile("help.stderr");
    /* Help message should start with name of program. */
    p = slurpfile(&plen, "help.stdout");
    failure("Help output should be long enough.");
    assert(plen >= 7);
    failure("First line of help output should contain string 'bsdcpio'");
    assert(in_first_line(p, "bsdcpio"));
    /*
     * TODO: Extend this check to further verify that --help output
     * looks approximately right.
     */
    free(p);

    /* -h option should generate the same output. */
    r = systemf("%s -h >h.stdout 2>h.stderr", testprog);
    failure("-h should generate nothing to stderr.");
    assertEmptyFile("h.stderr");
    failure("stdout should be same for -h and --help");
    assertEqualFile("h.stdout", "help.stdout");

    /* -W help should be another synonym. */
    r = systemf("%s -W help >Whelp.stdout 2>Whelp.stderr", testprog);
    failure("-W help should generate nothing to stderr.");
    assertEmptyFile("Whelp.stderr");
    failure("stdout should be same for -W help and --help");
    assertEqualFile("Whelp.stdout", "help.stdout");
}

--- NEW FILE: test_option_m.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");


DEFINE_TEST(test_option_m)
{
    int r;

    /*
     * The reference archive has one file with an mtime in 1970, 1
     * second after the start of the epoch.
     */

    /* Restored without -m, the result should have a current mtime. */
    assertMakeDir("without-m", 0755);
    assertChdir("without-m");
    extract_reference_file("test_option_m.cpio");
    r = systemf("%s --no-preserve-owner -i < test_option_m.cpio >out 2>err", testprog);
    assertEqualInt(r, 0);
    assertEmptyFile("out");
    assertTextFileContents("1 block\n", "err");
    /* Should have been created within the last few seconds. */
    assertFileMtimeRecent("file");

    /* With -m, it should have an mtime in 1970. */
    assertChdir("..");
    assertMakeDir("with-m", 0755);
    assertChdir("with-m");
    extract_reference_file("test_option_m.cpio");
    r = systemf("%s --no-preserve-owner -im < test_option_m.cpio >out 2>err", testprog);
    assertEqualInt(r, 0);
    assertEmptyFile("out");
    assertTextFileContents("1 block\n", "err");
    /*
     * mtime in reference archive is '1' == 1 second after
     * midnight Jan 1, 1970 UTC.
     */
    assertFileMtime("file", 1, 0);
}

--- NEW FILE: test_gcpio_compat_ref_nosym.crc.uu ---
begin 644 test_gcpio_compat_ref_nosym.crc
M,#<P-S`R,#`U-D9!1$4P,#`P-#%&1#`P,#`P,T4X,#`P,#`S13 at P,#`P,#`P
M,C1!040Q14)",#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P0D(P,35"
M,#`S-C`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#(P,#4V1D%$0S`P,#`X
M,4$T,#`P,#`S13 at P,#`P,#-%.#`P,#`P,#`R-$%!1#%%0D(P,#`P,#`P,#`P
M,#`P,#`P,#`P,#`P-30P,#`P,#!"0C`Q-4(P,#(W,#`P,#`P,#4P,#`P,#`P
M,&9I;&4``#`W,#<P,C`P-39&041#,#`P,#@Q030P,#`P,#-%.#`P,#`P,T4X
M,#`P,#`P,#(T04%$,45"0C`P,#`P,#!!,#`P,#`P,#`P,#`P,#`U-#`P,#`P
M,$)",#$U0C`P,C<P,#`P,#`P.3`P,#`P,44W;&EN:V9I;&4``#$R,S0U-C<X
M.0H``#`W,#<P,C`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
M,#`P,#$P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
M,#`P,#`P,#`P,#`P,#`P0C`P,#`P,#`P5%)!24Q%4B$A(0``````````````
1````````````````````````
`
end

--- NEW FILE: test_gcpio_compat_ref.crc.uu ---
$FreeBSD$
begin 644 test_gcpio_compat_ref.crc
M,#<P-S`R,#`S,S<W86$P,#`P.#%A-#`P,#`P,V4X,#`P,#`S93 at P,#`P,#`P
M,C0W,&0Y.3<W,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4Y,#`P,#`P,#`P,#`P
M,#`P,#`P,#`P,#`U,#`P,#`P,#!F:6QE```P-S`W,#(P,#,S-S=A83`P,#`X
M,6$T,#`P,#`S93 at P,#`P,#-E.#`P,#`P,#`R-#<P9#DY-S<P,#`P,#`P83`P
M,#`P,#`P,#`P,#`P-3DP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#DP,#`P,#%E
M-VQI;FMF:6QE```Q,C,T-38W.#D*```P-S`W,#(P,#,S-S=A8C`P,#!A,65D
M,#`P,#`S93 at P,#`P,#-E.#`P,#`P,#`Q-#<P9#DY.#0P,#`P,#`P-#`P,#`P
M,#`P,#`P,#`P-3DP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#@P,#`P,#`P,'-Y
M;6QI;FL```!F:6QE,#<P-S`R,#`S,S<W864P,#`P-#%F9#`P,#`P,V4X,#`P
M,#`S93 at P,#`P,#`P,C0W,&0Y.3 at U,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4Y
M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#(P
M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P
M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
M,#`P,&(P,#`P,#`P,%1204E,15(A(2$`````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
B````````````````````````````````````````````````
`
end

--- NEW FILE: test_option_l.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

DEFINE_TEST(test_option_l)
{
    int r;

    /* Create a file. */
    assertMakeFile("f", 0644, "a");

    /* Copy the file to the "copy" dir. */
    r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
        testprog);
    assertEqualInt(r, 0);

    /* Check that the copy is a true copy and not a link. */
    assertIsNotHardlink("f", "copy/f");

    /* Copy the file to the "link" dir with the -l option. */
    r = systemf("echo f | %s -pld link >link.out 2>link.err",
        testprog);
    assertEqualInt(r, 0);

    /* Check that this is a link and not a copy. */
    assertIsHardlink("f", "link/f");
}

--- NEW FILE: test_pathmatch.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

#include "pathmatch.h"

/*
 * Verify that the pattern matcher implements the wildcard logic specified
 * in SUSv2 for the cpio command.  This is essentially the
 * shell glob syntax:
 *   * - matches any sequence of chars, including '/'
 *   ? - matches any single char, including '/'
 *   [...] - matches any of a set of chars, '-' specifies a range,
 *        initial '!' is undefined
 *
 * The specification in SUSv2 is a bit incomplete, I assume the following:
 *   Trailing '-' in [...] is not special.
 *
 * TODO: Figure out if there's a good way to extend this to handle
 * Windows paths that use '\' as a path separator.  <sigh>
 */

DEFINE_TEST(test_pathmatch)
{
    assertEqualInt(1, lafe_pathmatch("a/b/c", "a/b/c", 0));
    assertEqualInt(0, lafe_pathmatch("a/b/", "a/b/c", 0));
    assertEqualInt(0, lafe_pathmatch("a/b", "a/b/c", 0));
    assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b/", 0));
    assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b", 0));

    /* Empty pattern only matches empty string. */
    assertEqualInt(1, lafe_pathmatch("","", 0));
    assertEqualInt(0, lafe_pathmatch("","a", 0));
    assertEqualInt(1, lafe_pathmatch("*","", 0));
    assertEqualInt(1, lafe_pathmatch("*","a", 0));
    assertEqualInt(1, lafe_pathmatch("*","abcd", 0));
    /* SUSv2: * matches / */
    assertEqualInt(1, lafe_pathmatch("*","abcd/efgh/ijkl", 0));
    assertEqualInt(1, lafe_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
    assertEqualInt(1, lafe_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
    assertEqualInt(1, lafe_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0));
    assertEqualInt(0, lafe_pathmatch("?", "", 0));
    assertEqualInt(0, lafe_pathmatch("?", "\0", 0));
    assertEqualInt(1, lafe_pathmatch("?", "a", 0));
    assertEqualInt(0, lafe_pathmatch("?", "ab", 0));
    assertEqualInt(1, lafe_pathmatch("?", ".", 0));
    assertEqualInt(1, lafe_pathmatch("?", "?", 0));
    assertEqualInt(1, lafe_pathmatch("a", "a", 0));
    assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
    assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
    assertEqualInt(1, lafe_pathmatch("a?c", "abc", 0));
    /* SUSv2: ? matches / */
    assertEqualInt(1, lafe_pathmatch("a?c", "a/c", 0));
    assertEqualInt(1, lafe_pathmatch("a?*c*", "a/c", 0));
    assertEqualInt(1, lafe_pathmatch("*a*", "a/c", 0));
    assertEqualInt(1, lafe_pathmatch("*a*", "/a/c", 0));
    assertEqualInt(1, lafe_pathmatch("*a*", "defaaaaaaa", 0));
    assertEqualInt(0, lafe_pathmatch("a*", "defghi", 0));
    assertEqualInt(0, lafe_pathmatch("*a*", "defghi", 0));

    /* Character classes */
    assertEqualInt(1, lafe_pathmatch("abc[def", "abc[def", 0));
    assertEqualInt(0, lafe_pathmatch("abc[def]", "abc[def", 0));
    assertEqualInt(0, lafe_pathmatch("abc[def", "abcd", 0));
    assertEqualInt(1, lafe_pathmatch("abc[def]", "abcd", 0));
    assertEqualInt(1, lafe_pathmatch("abc[def]", "abce", 0));
    assertEqualInt(1, lafe_pathmatch("abc[def]", "abcf", 0));
    assertEqualInt(0, lafe_pathmatch("abc[def]", "abcg", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abcd", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abc*", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d*f]", "abcdefghi", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d*", "abcdefghi", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d*", "abc[defghi", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcd", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abce", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcf", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d-f]", "abcg", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abca", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcd", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abce", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcf", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcg", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abch", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abci", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcj", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abck", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcl", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abc-", 0));

    /* [] matches nothing, [!] is the same as ? */
    assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcdefg", 0));
    assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcqefg", 0));
    assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcefg", 0));
    assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcdefg", 0));
    assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcqefg", 0));
    assertEqualInt(0, lafe_pathmatch("abc[!]efg", "abcefg", 0));

    /* I assume: Trailing '-' is non-special. */
    assertEqualInt(0, lafe_pathmatch("abc[d-fh-]", "abcl", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abch", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));

    /* ']' can be backslash-quoted within a character class. */
    assertEqualInt(1, lafe_pathmatch("abc[\\]]", "abc]", 0));
    assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abc]", 0));
    assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abcd", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abc]", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abcd", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d]e]", "abcde]", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d\\]e]", "abc]", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d\\]e]", "abcd]e", 0));
    assertEqualInt(0, lafe_pathmatch("abc[d]e]", "abc]", 0));

    /* backslash-quoted chars can appear as either end of a range. */
    assertEqualInt(1, lafe_pathmatch("abc[\\d-f]gh", "abcegh", 0));
    assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abcggh", 0));
    assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d-\\f]gh", "abcegh", 0));
    assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
    assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
    /* backslash-quoted '-' isn't special. */
    assertEqualInt(0, lafe_pathmatch("abc[d\\-f]gh", "abcegh", 0));
    assertEqualInt(1, lafe_pathmatch("abc[d\\-f]gh", "abc-gh", 0));

    /* Leading '!' negates a character class. */
    assertEqualInt(0, lafe_pathmatch("abc[!d]", "abcd", 0));
    assertEqualInt(1, lafe_pathmatch("abc[!d]", "abce", 0));
    assertEqualInt(1, lafe_pathmatch("abc[!d]", "abcc", 0));
    assertEqualInt(0, lafe_pathmatch("abc[!d-z]", "abcq", 0));
    assertEqualInt(1, lafe_pathmatch("abc[!d-gi-z]", "abch", 0));
    assertEqualInt(1, lafe_pathmatch("abc[!fgijkl]", "abch", 0));
    assertEqualInt(0, lafe_pathmatch("abc[!fghijkl]", "abch", 0));

    /* Backslash quotes next character. */
    assertEqualInt(0, lafe_pathmatch("abc\\[def]", "abc\\d", 0));
    assertEqualInt(1, lafe_pathmatch("abc\\[def]", "abc[def]", 0));
    assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc[def]", 0));
    assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc\\[def]", 0));
    assertEqualInt(1, lafe_pathmatch("abc\\\\[def]", "abc\\d", 0));
    assertEqualInt(1, lafe_pathmatch("abcd\\", "abcd\\", 0));
    assertEqualInt(0, lafe_pathmatch("abcd\\", "abcd\\[", 0));
    assertEqualInt(0, lafe_pathmatch("abcd\\", "abcde", 0));
    assertEqualInt(0, lafe_pathmatch("abcd\\[", "abcd\\", 0));

    /*
     * Because '.' and '/' have special meanings, we can
     * identify many equivalent paths even if they're expressed
     * differently.  (But quoting a character with '\\' suppresses
     * special meanings!)
     */
    assertEqualInt(0, lafe_pathmatch("a/b/", "a/bc", 0));
    assertEqualInt(1, lafe_pathmatch("a/./b", "a/b", 0));
    assertEqualInt(0, lafe_pathmatch("a\\/./b", "a/b", 0));
    assertEqualInt(0, lafe_pathmatch("a/\\./b", "a/b", 0));
    assertEqualInt(0, lafe_pathmatch("a/.\\/b", "a/b", 0));
    assertEqualInt(0, lafe_pathmatch("a\\/\\.\\/b", "a/b", 0));
    assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def/", 0));
    assertEqualInt(1, lafe_pathmatch("abc/def", "./././abc/./def", 0));
    assertEqualInt(1, lafe_pathmatch("abc/def/././//", "./././abc/./def/", 0));
    assertEqualInt(1, lafe_pathmatch(".////abc/.//def", "./././abc/./def", 0));
    assertEqualInt(1, lafe_pathmatch("./abc?def/", "abc/def/", 0));
    failure("\"?./\" is not the same as \"/./\"");
    assertEqualInt(0, lafe_pathmatch("./abc?./def/", "abc/def/", 0));
    failure("Trailing '/' should match no trailing '/'");
    assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def", 0));
    failure("Trailing '/./' is still the same directory.");
    assertEqualInt(1, lafe_pathmatch("./abc/./def/./", "abc/def", 0));
    failure("Trailing '/.' is still the same directory.");
    assertEqualInt(1, lafe_pathmatch("./abc/./def/.", "abc/def", 0));
    assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/", 0));
    failure("Trailing '/./' is still the same directory.");
    assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/./", 0));
    failure("Trailing '/.' is still the same directory.");
    assertEqualInt(1, lafe_pathmatch("./abc*/./def", "abc/def/.", 0));

    /* Matches not anchored at beginning. */
    assertEqualInt(0,
        lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
    assertEqualInt(1,
        lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
    assertEqualInt(0,
        lafe_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
    assertEqualInt(1,
        lafe_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
    assertEqualInt(0,
        lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
    assertEqualInt(0,
        lafe_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));

    /* Matches not anchored at end. */
    assertEqualInt(0,
        lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(0,
        lafe_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(0,
        lafe_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(0,
        lafe_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(1,
        lafe_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
    assertEqualInt(0,
        lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
}

--- NEW FILE: test_option_d.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");


DEFINE_TEST(test_option_d)
{
    int r;

    /*
     * Create a file in a directory.
     */
    assertMakeDir("dir", 0755);
    assertMakeFile("dir/file", 0644, NULL);

    /* Create an archive. */
    r = systemf("echo dir/file | %s -o > archive.cpio 2>archive.err", testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "archive.err");
    assertFileSize("archive.cpio", 512);

    /* Dearchive without -d, this should fail. */
    assertMakeDir("without-d", 0755);
    assertChdir("without-d");
    r = systemf("%s -i < ../archive.cpio >out 2>err", testprog);
    assertEqualInt(r, 0);
    assertEmptyFile("out");
    /* And the file should not be restored. */
    assertFileNotExists("dir/file");

    /* Dearchive with -d, this should succeed. */
    assertChdir("..");
    assertMakeDir("with-d", 0755);
    assertChdir("with-d");
    r = systemf("%s -id < ../archive.cpio >out 2>err", testprog);
    assertEqualInt(r, 0);
    assertEmptyFile("out");
    assertTextFileContents("1 block\n", "err");
    /* And the file should be restored. */
    assertFileExists("dir/file");
}

--- NEW FILE: test_option_lzma.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

DEFINE_TEST(test_option_lzma)
{
    char *p;
    int r;
    size_t s;

    /* Create a file. */
    assertMakeFile("f", 0644, "a");

    /* Archive it with lzma compression. */
    r = systemf("echo f | %s -o --lzma >archive.out 2>archive.err",
        testprog);
    p = slurpfile(&s, "archive.err");
    p[s] = '\0';
    if (r != 0) {
        if (strstr(p, "compression not available") != NULL) {
            skipping("This version of bsdcpio was compiled "
                "without lzma support");
            return;
        }
        failure("--lzma option is broken");
        assertEqualInt(r, 0);
        return;
    }
    /* Check that the archive file has an lzma signature. */
    p = slurpfile(&s, "archive.out");
    assert(s > 2);
    assertEqualMem(p, "\x5d\00\00", 3);
}

--- NEW FILE: test_basic.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_basic.c,v 1.4 2008/08/25 06:39:29 kientzle Exp $");

static void
verify_files(const char *msg)
{
    /*
     * Verify unpacked files.
     */

    /* Regular file with 2 links. */
    assertIsReg("file", 0644);
    failure(msg);
    assertFileSize("file", 10);
    assertFileNLinks("file", 2);

    /* Another name for the same file. */
    assertIsHardlink("linkfile", "file");

    /* Symlink */
    if (canSymlink())
        assertIsSymlink("symlink", "file");

    /* Another file with 1 link and different permissions. */
    assertIsReg("file2", 0777);
    assertFileSize("file2", 10);
    assertFileNLinks("file2", 1);

    /* dir */
    assertIsDir("dir", 0775);
}

static void
basic_cpio(const char *target,
    const char *pack_options,
    const char *unpack_options,
    const char *se)
{
    int r;

    if (!assertMakeDir(target, 0775))
        return;

    /* Use the cpio program to create an archive. */
    r = systemf("%s -o %s < filelist >%s/archive 2>%s/pack.err",
        testprog, pack_options, target, target);
    failure("Error invoking %s -o %s", testprog, pack_options);
    assertEqualInt(r, 0);

    assertChdir(target);

    /* Verify stderr. */
    failure("Expected: %s, options=%s", se, pack_options);
    assertTextFileContents(se, "pack.err");

    /*
     * Use cpio to unpack the archive into another directory.
     */
    r = systemf("%s -i %s< archive >unpack.out 2>unpack.err",
        testprog, unpack_options);
    failure("Error invoking %s -i %s", testprog, unpack_options);
    assertEqualInt(r, 0);

    /* Verify stderr. */
    failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target);
    assertTextFileContents(se, "unpack.err");

    verify_files(pack_options);

    assertChdir("..");
}

static void
passthrough(const char *target)
{
    int r;

    if (!assertMakeDir(target, 0775))
        return;

    /*
     * Use cpio passthrough mode to copy files to another directory.
     */
    r = systemf("%s -p %s <filelist >%s/stdout 2>%s/stderr",
        testprog, target, target, target);
    failure("Error invoking %s -p", testprog);
    assertEqualInt(r, 0);

    assertChdir(target);

    /* Verify stderr. */
    failure("Error invoking %s -p in dir %s",
        testprog, target);
    assertTextFileContents("1 block\n", "stderr");

    verify_files("passthrough");
    assertChdir("..");
}

DEFINE_TEST(test_basic)
{
    FILE *filelist;
    const char *msg;

    assertUmask(0);

    /*
     * Create an assortment of files on disk.
     */
    filelist = fopen("filelist", "w");

    /* File with 10 bytes content. */
    assertMakeFile("file", 0644, "1234567890");
    fprintf(filelist, "file\n");

    /* hardlink to above file. */
    assertMakeHardlink("linkfile", "file");
    fprintf(filelist, "linkfile\n");

    /* Symlink to above file. */
    if (canSymlink()) {
        assertMakeSymlink("symlink", "file");
        fprintf(filelist, "symlink\n");
    }

    /* Another file with different permissions. */
    assertMakeFile("file2", 0777, "1234567890");
    fprintf(filelist, "file2\n");

    /* Directory. */
    assertMakeDir("dir", 0775);
    fprintf(filelist, "dir\n");
    /* All done. */
    fclose(filelist);

    assertUmask(022);

    /* Archive/dearchive with a variety of options. */
    msg = canSymlink() ? "2 blocks\n" : "1 block\n";
    basic_cpio("copy", "", "", msg);
    basic_cpio("copy_odc", "--format=odc", "", msg);
    basic_cpio("copy_newc", "-H newc", "", "2 blocks\n");
    basic_cpio("copy_cpio", "-H odc", "", msg);
    msg = canSymlink() ? "9 blocks\n" : "8 blocks\n";
    basic_cpio("copy_ustar", "-H ustar", "", msg);

    /* Copy in one step using -p */
    passthrough("passthrough");
}

--- NEW FILE: test_option_u.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <sys/utime.h>
#else
#include <utime.h>
#endif
__FBSDID("$FreeBSD$");

DEFINE_TEST(test_option_u)
{
    struct utimbuf times;
    char *p;
    size_t s;
    int r;

    /* Create a file. */
    assertMakeFile("f", 0644, "a");

    /* Copy the file to the "copy" dir. */
    r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
        testprog);
    assertEqualInt(r, 0);

    /* Check that the file contains only a single "a" */
    p = slurpfile(&s, "copy/f");
    assertEqualInt(s, 1);
    assertEqualMem(p, "a", 1);

    /* Recreate the file with a single "b" */
    assertMakeFile("f", 0644, "b");

    /* Set the mtime to the distant past. */
    memset(&times, 0, sizeof(times));
    times.actime = 1;
    times.modtime = 3;
    assertEqualInt(0, utime("f", &times));

    /* Copy the file to the "copy" dir. */
    r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
        testprog);
    assertEqualInt(r, 0);

    /* Verify that the file hasn't changed (it wasn't overwritten) */
    p = slurpfile(&s, "copy/f");
    assertEqualInt(s, 1);
    assertEqualMem(p, "a", 1);

    /* Copy the file to the "copy" dir with -u (force) */
    r = systemf("echo f | %s -pud copy >copy.out 2>copy.err",
        testprog);
    assertEqualInt(r, 0);

    /* Verify that the file has changed (it was overwritten) */
    p = slurpfile(&s, "copy/f");
    assertEqualInt(s, 1);
    assertEqualMem(p, "b", 1);
}

--- NEW FILE: test_gcpio_compat_ref_nosym.newc.uu ---
begin 644 test_gcpio_compat_ref_nosym.newc
M,#<P-S`Q,#`U-D9!1$4P,#`P-#%&1#`P,#`P,T4X,#`P,#`S13 at P,#`P,#`P
M,C1!040Q14)",#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P0D(P,35"
M,#`S-C`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#$P,#4V1D%$0S`P,#`X
M,4$T,#`P,#`S13 at P,#`P,#-%.#`P,#`P,#`R-$%!1#%%0D(P,#`P,#`P,#`P
M,#`P,#`P,#`P,#`P-30P,#`P,#!"0C`Q-4(P,#(W,#`P,#`P,#4P,#`P,#`P
M,&9I;&4``#`W,#<P,3`P-39&041#,#`P,#@Q030P,#`P,#-%.#`P,#`P,T4X
M,#`P,#`P,#(T04%$,45"0C`P,#`P,#!!,#`P,#`P,#`P,#`P,#`U-#`P,#`P
M,$)",#$U0C`P,C<P,#`P,#`P.3`P,#`P,#`P;&EN:V9I;&4``#$R,S0U-C<X
M.0H``#`W,#<P,3`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
M,#`P,#$P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
M,#`P,#`P,#`P,#`P,#`P0C`P,#`P,#`P5%)!24Q%4B$A(0``````````````
1````````````````````````
`
end

--- NEW FILE: test_option_Z_upper.c ---
/*-
 * Copyright (c) 2003-2009 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

DEFINE_TEST(test_option_Z_upper)
{
    char *p;
    int r;
    size_t s;

    /* Create a file. */
    assertMakeFile("f", 0644, "a");

    /* Archive it with compress compression. */
    r = systemf("echo f | %s -oZ >archive.out 2>archive.err",
        testprog);
    p = slurpfile(&s, "archive.err");
    p[s] = '\0';
    if (r != 0) {
        if (strstr(p, "compression not available") != NULL) {
            skipping("This version of bsdcpio was compiled "
                "without compress support");
            return;
        }
        failure("-Z option is broken");
        assertEqualInt(r, 0);
        return;
    }
    /* Check that the archive file has a compress signature. */
    p = slurpfile(&s, "archive.out");
    assert(s > 2);
    assertEqualMem(p, "\x1f\x9d", 2);
}

--- NEW FILE: test_option_version.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

/*
 * Test that --version option works and generates reasonable output.
 */

static void
verify(const char *p, size_t s)
{
    const char *q = p;

    /* Version message should start with name of program, then space. */
    failure("version message too short:", p);
    if (!assert(s > 6))
        return;
    failure("Version message should begin with 'bsdcpio': %s", p);
    if (!assertEqualMem(q, "bsdcpio ", 8))
        /* If we're not testing bsdcpio, don't keep going. */
        return;
    q += 8; s -= 8;
    /* Version number is a series of digits and periods. */
    while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
        ++q;
        --s;
    }
    /* Version number terminated by space. */
    failure("Version: %s", p);
    assert(s > 1);
    /* Skip a single trailing a,b,c, or d. */
    if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
        ++q;
    failure("Version: %s", p);
    assert(*q == ' ');
    ++q; --s;
    /* Separator. */
    failure("Version: %s", p);
    assertEqualMem(q, "-- ", 3);
    q += 3; s -= 3;
    /* libarchive name and version number */
    assert(s > 11);
    failure("Version: %s", p);
    assertEqualMem(q, "libarchive ", 11);
    q += 11; s -= 11;
    /* Version number is a series of digits and periods. */
    while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
        ++q;
        --s;
    }
    /* Skip a single trailing a,b,c, or d. */
    if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
        ++q;
    /* All terminated by a newline. */
    assert(s >= 1);
    failure("Version: %s", p);
#if defined(_WIN32) && !defined(__CYGWIN__)
    assertEqualMem(q, "\r\n", 2);
#else
    assertEqualMem(q, "\n", 1);
#endif
}


DEFINE_TEST(test_option_version)
{
    int r;
    char *p;
    size_t s;

    r = systemf("%s --version >version.stdout 2>version.stderr", testprog);
    if (r != 0)
        r = systemf("%s -W version >version.stdout 2>version.stderr",
            testprog);
    failure("Unable to run either %s --version or %s -W version",
        testprog, testprog);
    if (!assert(r == 0))
        return;

    /* --version should generate nothing to stderr. */
    assertEmptyFile("version.stderr");
    /* Verify format of version message. */
    p = slurpfile(&s, "version.stdout");
    verify(p, s);
    free(p);
}

--- NEW FILE: test_owner_parse.c ---
/*-
 * Copyright (c) 2003-2009 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

#include "../cpio.h"
#include "err.h"

#if !defined(_WIN32)
#define ROOT "root"
static int root_uids[] = { 0 };
static int root_gids[] = { 0 };
#elif defined(__CYGWIN__)
/* On cygwin, the Administrator user most likely exists (unless
 * it has been renamed or is in a non-English localization), but
 * its primary group membership depends on how the user set up
 * their /etc/passwd. Likely values are 513 (None), 545 (Users),
 * or 544 (Administrators). Just check for one of those...
 * TODO: Handle non-English localizations...e.g. French 'Administrateur'
 *       Use CreateWellKnownSID() and LookupAccountName()?
 */
#define ROOT "Administrator"
static int root_uids[] = { 500 };
static int root_gids[] = { 513, 545, 544 };
#endif

#if defined(ROOT)
static int
int_in_list(int i, int *l, size_t n)
{
    while (n-- > 0)
        if (*l++ == i)
            return (1);
    failure("%d", i);
    return (0);
}
#endif

DEFINE_TEST(test_owner_parse)
{
#if !defined(ROOT)
    skipping("No uid/gid configuration for this OS");
#else
    int uid, gid;

    assert(NULL == owner_parse(ROOT, &uid, &gid));
    assert(int_in_list(uid, root_uids,
        sizeof(root_uids)/sizeof(root_uids[0])));
    assertEqualInt(-1, gid);


    assert(NULL == owner_parse(ROOT ":", &uid, &gid));
    assert(int_in_list(uid, root_uids,
        sizeof(root_uids)/sizeof(root_uids[0])));
    assert(int_in_list(gid, root_gids,
        sizeof(root_gids)/sizeof(root_gids[0])));

    assert(NULL == owner_parse(ROOT ".", &uid, &gid));
    assert(int_in_list(uid, root_uids,
        sizeof(root_uids)/sizeof(root_uids[0])));
    assert(int_in_list(gid, root_gids,
        sizeof(root_gids)/sizeof(root_gids[0])));

    assert(NULL == owner_parse("111", &uid, &gid));
    assertEqualInt(111, uid);
    assertEqualInt(-1, gid);

    assert(NULL == owner_parse("112:", &uid, &gid));
    assertEqualInt(112, uid);
    /* Can't assert gid, since we don't know gid for user #112. */

    assert(NULL == owner_parse("113.", &uid, &gid));
    assertEqualInt(113, uid);
    /* Can't assert gid, since we don't know gid for user #113. */

    assert(NULL == owner_parse(":114", &uid, &gid));
    assertEqualInt(-1, uid);
    assertEqualInt(114, gid);

    assert(NULL == owner_parse(".115", &uid, &gid));
    assertEqualInt(-1, uid);
    assertEqualInt(115, gid);

    assert(NULL == owner_parse("116:117", &uid, &gid));
    assertEqualInt(116, uid);
    assertEqualInt(117, gid);

    /*
     * TODO: Lookup current user/group name, build strings and
     * use those to verify username/groupname lookups for ordinary
     * users.
     */

    assert(NULL != owner_parse(":nonexistentgroup", &uid, &gid));
    assert(NULL != owner_parse(ROOT ":nonexistentgroup", &uid, &gid));
    assert(NULL !=
        owner_parse("nonexistentuser:nonexistentgroup", &uid, &gid));
#endif
}

--- NEW FILE: test_0.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");

/*
 * This first test does basic sanity checks on the environment.  For
 * most of these, we just exit on failure.
 */
#if !defined(_WIN32) || defined(__CYGWIN__)
#define DEV_NULL "/dev/null"
#else
#define DEV_NULL "NUL"
#endif

DEFINE_TEST(test_0)
{
    struct stat st;

    failure("File %s does not exist?!", testprogfile);
    if (!assertEqualInt(0, stat(testprogfile, &st)))
        exit(1);

    failure("%s is not executable?!", testprogfile);
    if (!assert((st.st_mode & 0111) != 0))
        exit(1);

    /*
     * Try to succesfully run the program; this requires that
     * we know some option that will succeed.
     */
    if (0 == systemf("%s --version >" DEV_NULL, testprog)) {
        /* This worked. */
    } else if (0 == systemf("%s -W version >" DEV_NULL, testprog)) {
        /* This worked. */
    } else {
        failure("Unable to successfully run any of the following:\n"
            "  * %s --version\n"
            "  * %s -W version\n",
            testprog, testprog);
        assert(0);
    }

    /* TODO: Ensure that our reference files are available. */
}

--- NEW FILE: test_option_t.cpio.uu ---
$FreeBSD$
begin 644 test_option_t.cpio
M,#<P-S`W,#`P,3,Q-#4P,#8T,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P
M,#`P,#`P,#`P,#`P,#$P,#`P,#4P,#`P,#`P,#`P,&9I;&4`,#<P-S`W,#`P
M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P,#`P,#`P
M,#`P,#`P,#`P,3,P,#`P,#`P,#`P,%1204E,15(A(2$`````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
1````````````````````````
`
end

--- NEW FILE: test_gcpio_compat_ref.ustar.uu ---
$FreeBSD$
begin 644 test_gcpio_compat_ref.ustar
M9FEL90``````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````#`P,#`V-#0`,#`P,3<U,``P,#`Q-S4P`#`P,#`P,#`P,#$R
M`#$P-S`S,S$T-38W`#`P,3$S-C,`,```````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````!U<W1A<@`P,'1I;0``
M````````````````````````````````````=&EM````````````````````
M```````````````````P,#`P,#`P`#`P,#`P,#``````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M```````````````````````Q,C,T-38W.#D*````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````````````````````````````&QI;FMF:6QE````
M````````````````````````````````````````````````````````````
M```````````````````````````````````````````````````````````P
M,#`P-C0T`#`P,#$W-3``,#`P,3<U,``P,#`P,#`P,#`P,``Q,#<P,S,Q-#4V
M-P`P,#$S,#<W`#%F:6QE````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````=7-T87(`,#!T:6T`````````````````
M`````````````````````'1I;0``````````````````````````````````
M````,#`P,#`P,``P,#`P,#`P````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````<WEM;&EN:P``````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````````````#`P,#`W-34`,#`P,3<U,``P,#`Q-S4P`#`P,#`P
M,#`P,#`P`#$P-S`S,S$T-C`T`#`P,3(W-C0`,F9I;&4`````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````````````!U<W1A<@`P
M,'1I;0``````````````````````````````````````=&EM````````````
M```````````````````````````P,#`P,#`P`#`P,#`P,#``````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````!D:7(O````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````,#`P,#<W-0`P,#`Q
M-S4P`#`P,#$W-3``,#`P,#`P,#`P,#``,3`W,#,S,30V,#4`,#`Q,3,P,0`U
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````'5S=&%R`#`P=&EM````````````````````````````````
M``````!T:6T``````````````````````````````````````#`P,#`P,#``
M,#`P,#`P,```````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
=````````````````````````````````````````
`
end

--- NEW FILE: test_format_newc.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_format_newc.c,v 1.2 2008/08/22 02:09:10 kientzle Exp $");

/* Number of bytes needed to pad 'n' to multiple of 'block', assuming
 * that 'block' is a power of two. This trick can be more easily
 * remembered as -n & (block - 1), but many compilers quite reasonably
 * warn about "-n" when n is an unsigned value.  (~(n) + 1) is the
 * same thing, but written in a way that won't offend anyone. */
#define PAD(n, block)  ((~(n) + 1) & ((block) - 1))

static int
is_hex(const char *p, size_t l)
{
    while (l > 0) {
        if ((*p >= '0' && *p <= '9')
            || (*p >= 'a' && *p <= 'f')
            || (*p >= 'A' && *p <= 'F'))
        {
            --l;
            ++p;
        } else
            return (0);

    }
    return (1);
}

static int
from_hex(const char *p, size_t l)
{
    int r = 0;

    while (l > 0) {
        r *= 16;
        if (*p >= 'a' && *p <= 'f')
            r += *p + 10 - 'a';
        else if (*p >= 'A' && *p <= 'F')
            r += *p + 10 - 'A';
        else
            r += *p - '0';
        --l;
        ++p;
    }
    return (r);
}

DEFINE_TEST(test_format_newc)
{
    FILE *list;
    int r;
    int devmajor, devminor, ino, gid;
    int uid = -1;
    time_t t, t2, now;
    char *p, *e;
    size_t s, fs, ns;

    assertUmask(0);

#if !defined(_WIN32)
    uid = getuid();
#endif

    /*
     * Create an assortment of files.
     * TODO: Extend this to cover more filetypes.
     */
    list = fopen("list", "w");

    /* "file1" */
    assertMakeFile("file1", 0644, "1234567890");
    fprintf(list, "file1\n");

    /* "hardlink" */
    assertMakeHardlink("hardlink", "file1");
    fprintf(list, "hardlink\n");

    /* Another hardlink, but this one won't be archived. */
    assertMakeHardlink("hardlink2", "file1");

    /* "symlink" */
    if (canSymlink()) {
        assertMakeSymlink("symlink", "file1");
        fprintf(list, "symlink\n");
    }

    /* "dir" */
    assertMakeDir("dir", 0775);
    fprintf(list, "dir\n");

    /* Record some facts about what we just created: */
    now = time(NULL); /* They were all created w/in last two seconds. */

    /* Use the cpio program to create an archive. */
    fclose(list);
    r = systemf("%s -o --format=newc <list >newc.out 2>newc.err",
        testprog);
    if (!assertEqualInt(r, 0))
        return;

    /* Verify that nothing went to stderr. */
    if (canSymlink()) {
        assertTextFileContents("2 blocks\n", "newc.err");
    } else {
        assertTextFileContents("1 block\n", "newc.err");
    }

    /* Verify that stdout is a well-formed cpio file in "newc" format. */
    p = slurpfile(&s, "newc.out");
    assertEqualInt(s, canSymlink() ? 1024 : 512);
    e = p;

    /*
     * Some of these assertions could be stronger, but it's
     * a little tricky because they depend on the local environment.
     */

    /* First entry is "file1" */
    assert(is_hex(e, 110)); /* Entire header is octal digits. */
    assertEqualMem(e + 0, "070701", 6); /* Magic */
    ino = from_hex(e + 6, 8); /* ino */
#if defined(_WIN32) && !defined(__CYGWIN__)
    /* Group members bits and others bits do not work. */ 
    assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */
#else
    assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
#endif  
    if (uid < 0)
        uid = from_hex(e + 22, 8);
    assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
    gid = from_hex(e + 30, 8); /* gid */
    assertEqualMem(e + 38, "00000003", 8); /* nlink */
    t = from_hex(e + 46, 8); /* mtime */
    failure("t=0x%08x now=0x%08x=%d", t, now, now);
    assert(t <= now); /* File wasn't created in future. */
    failure("t=0x%08x now - 2=0x%08x = %d", t, now - 2, now - 2);
    assert(t >= now - 2); /* File was created w/in last 2 secs. */
    failure("newc format stores body only with last appearance of a link\n"
        "       first appearance should be empty, so this file size\n"
        "       field should be zero");
    assertEqualInt(0, from_hex(e + 54, 8)); /* File size */
    fs = from_hex(e + 54, 8);
    fs += PAD(fs, 4);
    devmajor = from_hex(e + 62, 8); /* devmajor */
    devminor = from_hex(e + 70, 8); /* devminor */
    assert(is_hex(e + 78, 8)); /* rdevmajor */
    assert(is_hex(e + 86, 8)); /* rdevminor */
    assertEqualMem(e + 94, "00000006", 8); /* Name size */
    ns = from_hex(e + 94, 8);
    ns += PAD(ns + 2, 4);
    assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
    assertEqualMem(e + 110, "file1\0", 6); /* Name contents */
    /* Since there's another link, no file contents here. */
    /* But add in file size so that an error here doesn't cascade. */
    e += 110 + fs + ns;

    if (canSymlink()) {
        /* "symlink" pointing to "file1" */
        assert(is_hex(e, 110));
        assertEqualMem(e + 0, "070701", 6); /* Magic */
        assert(is_hex(e + 6, 8)); /* ino */
        assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */
        assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
        assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
        assertEqualMem(e + 38, "00000001", 8); /* nlink */
        t2 = from_hex(e + 46, 8); /* mtime */
        failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
        assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
        assertEqualMem(e + 54, "00000005", 8); /* File size */
        fs = from_hex(e + 54, 8);
        fs += PAD(fs, 4);
        assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
        assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
        assert(is_hex(e + 78, 8)); /* rdevmajor */
        assert(is_hex(e + 86, 8)); /* rdevminor */
        assertEqualMem(e + 94, "00000008", 8); /* Name size */
        ns = from_hex(e + 94, 8);
        ns += PAD(ns + 2, 4);
        assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
        assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */
        assertEqualMem(e + 110 + ns, "file1\0\0\0", 8); /* symlink target */
        e += 110 + fs + ns;
    }

    /* "dir" */
    assert(is_hex(e, 110));
    assertEqualMem(e + 0, "070701", 6); /* Magic */
    assert(is_hex(e + 6, 8)); /* ino */
#if defined(_WIN32) && !defined(__CYGWIN__)
    /* Group members bits and others bits do not work. */
    assertEqualInt(0x41c0, from_hex(e + 14, 8) & 0xffc0); /* Mode */
#else
    /* Mode: sgid bit sometimes propagates from parent dirs, ignore it. */
    assertEqualInt(040775, from_hex(e + 14, 8) & ~02000);
#endif
    assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
    assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
#ifndef NLINKS_INACCURATE_FOR_DIRS
    assertEqualMem(e + 38, "00000002", 8); /* nlink */
#endif
    t2 = from_hex(e + 46, 8); /* mtime */
    failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
    assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
    assertEqualMem(e + 54, "00000000", 8); /* File size */
    fs = from_hex(e + 54, 8);
    fs += PAD(fs, 4);
    assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
    assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
    assert(is_hex(e + 78, 8)); /* rdevmajor */
    assert(is_hex(e + 86, 8)); /* rdevminor */
    assertEqualMem(e + 94, "00000004", 8); /* Name size */
    ns = from_hex(e + 94, 8);
    ns += PAD(ns + 2, 4);
    assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
    assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */
    e += 110 + fs + ns;

    /* Hardlink identical to "file1" */
    /* Since we only wrote two of the three links to this
     * file, this link should get deferred by the hardlink logic. */
    assert(is_hex(e, 110));
    assertEqualMem(e + 0, "070701", 6); /* Magic */
    failure("If these aren't the same, then the hardlink detection failed to match them.");
    assertEqualInt(ino, from_hex(e + 6, 8)); /* ino */
#if defined(_WIN32) && !defined(__CYGWIN__)
    /* Group members bits and others bits do not work. */ 
    assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */
#else
    assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
#endif
    assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
    assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
    assertEqualMem(e + 38, "00000003", 8); /* nlink */
    t2 = from_hex(e + 46, 8); /* mtime */
    failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);
    assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
    assertEqualInt(10, from_hex(e + 54, 8)); /* File size */
    fs = from_hex(e + 54, 8);
    fs += PAD(fs, 4);
    assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
    assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
    assert(is_hex(e + 78, 8)); /* rdevmajor */
    assert(is_hex(e + 86, 8)); /* rdevminor */
    assertEqualMem(e + 94, "00000009", 8); /* Name size */
    ns = from_hex(e + 94, 8);
    ns += PAD(ns + 2, 4);
    assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
    assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */
    assertEqualMem(e + 110 + ns, "1234567890\0\0", 12); /* File contents */
    e += 110 + ns + fs;

    /* Last entry is end-of-archive marker. */
    assert(is_hex(e, 110));
    assertEqualMem(e + 0, "070701", 6); /* Magic */
    assertEqualMem(e + 8, "00000000", 8); /* ino */
    assertEqualMem(e + 14, "00000000", 8); /* mode */
    assertEqualMem(e + 22, "00000000", 8); /* uid */
    assertEqualMem(e + 30, "00000000", 8); /* gid */
    assertEqualMem(e + 38, "00000001", 8); /* nlink */
    assertEqualMem(e + 46, "00000000", 8); /* mtime */
    assertEqualMem(e + 54, "00000000", 8); /* size */
    assertEqualMem(e + 62, "00000000", 8); /* devmajor */
    assertEqualMem(e + 70, "00000000", 8); /* devminor */
    assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */
    assertEqualMem(e + 86, "00000000", 8); /* rdevminor */
    assertEqualInt(11, from_hex(e + 94, 8)); /* name size */
    assertEqualMem(e + 102, "00000000", 8); /* check field */
    assertEqualMem(e + 110, "TRAILER!!!\0\0", 12); /* Name */

    free(p);
}

--- NEW FILE: test_gcpio_compat_ref.bin.uu ---
$FreeBSD$
begin 644 test_gcpio_compat_ref.bin
MQW%9`*IWI('H`^@#`@````U'=YD%````"@!F:6QE```Q,C,T-38W.#D*QW%9
M`*IWI('H`^@#`@````U'=YD)````"@!L:6YK9FEL90``,3(S-#4V-S at Y"L=Q
M60"K=^VAZ`/H`P$````-1X29"`````0`<WEM;&EN:P!F:6QEQW%9`*YW_4'H
M`^@#`@````U'A9D$``````!D:7(`QW$``````````````0`````````+````
M``!44D%)3$52(2$A````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
1````````````````````````
`
end

--- NEW FILE: test_gcpio_compat_ref.newc.uu ---
$FreeBSD$
begin 644 test_gcpio_compat_ref.newc
M,#<P-S`Q,#`S,S<W86$P,#`P.#%A-#`P,#`P,V4X,#`P,#`S93 at P,#`P,#`P
M,C0W,&0Y.3<W,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4Y,#`P,#`P,#`P,#`P
M,#`P,#`P,#`P,#`U,#`P,#`P,#!F:6QE```P-S`W,#$P,#,S-S=A83`P,#`X
M,6$T,#`P,#`S93 at P,#`P,#-E.#`P,#`P,#`R-#<P9#DY-S<P,#`P,#`P83`P
M,#`P,#`P,#`P,#`P-3DP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#DP,#`P,#`P
M,&QI;FMF:6QE```Q,C,T-38W.#D*```P-S`W,#$P,#,S-S=A8C`P,#!A,65D
M,#`P,#`S93 at P,#`P,#-E.#`P,#`P,#`Q-#<P9#DY.#0P,#`P,#`P-#`P,#`P
M,#`P,#`P,#`P-3DP,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#@P,#`P,#`P,'-Y
M;6QI;FL```!F:6QE,#<P-S`Q,#`S,S<W864P,#`P-#%F9#`P,#`P,V4X,#`P
M,#`S93 at P,#`P,#`P,C0W,&0Y.3 at U,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4Y
M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`T,#`P,#`P,#!D:7(````P-S`W,#$P
M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P
M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
M,#`P,&(P,#`P,#`P,%1204E,15(A(2$`````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
B````````````````````````````````````````````````
`
end

--- NEW FILE: test_option_f.cpio.uu ---
$FreeBSD$
begin 644 test_option_f.cpio
M,#<P-S`W,#`P,3,Q-C(Q-38Q,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P
M,#`P,3`W,S4Q,3(U,C8P,#`P,#4P,#`P,#`P,#`P,&$Q,C,`,#<P-S`W,#`P
M,3,Q-C(Q-38S,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P,#`P,3`W,S4Q
M,3(U-#`P,#`P,#4P,#`P,#`P,#`P,&$R,S0`,#<P-S`W,#`P,3,Q-C(Q-38R
M,3`P-C0T,#`Q-S4P,#`Q-S4P,#`P,#`Q,#`P,#`P,3`W,S4Q,3(U,S0P,#`P
M,#4P,#`P,#`P,#`P,&(Q,C,`,#<P-S`W,#`P,3,Q-C(Q-38T,3`P-C0T,#`Q
M-S4P,#`Q-S4P,#`P,#`Q,#`P,#`P,3`W,S4Q,3(U-#,P,#`P,#4P,#`P,#`P
M,#`P,&(R,S0`,#<P-S`W,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
M,#`P,#`Q,#`P,#`P,#`P,#`P,#`P,#`P,#`P,3,P,#`P,#`P,#`P,%1204E,
M15(A(2$`````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
1````````````````````````
`
end

--- NEW FILE: test_gcpio_compat.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_gcpio_compat.c,v 1.2 2008/08/22 02:27:06 kientzle Exp $");

static void
unpack_test(const char *from, const char *options, const char *se)
{
    int r;

    /* Create a work dir named after the file we're unpacking. */
    assertMakeDir(from, 0775);
    assertChdir(from);

    /*
     * Use cpio to unpack the sample archive
     */
    extract_reference_file(from);
    r = systemf("%s -i %s < %s >unpack.out 2>unpack.err",
        testprog, options, from);
    failure("Error invoking %s -i %s < %s",
        testprog, options, from);
    assertEqualInt(r, 0);

    /* Verify that nothing went to stderr. */
    if (canSymlink()) {
        failure("Error invoking %s -i %s < %s",
            testprog, options, from);
        assertTextFileContents(se, "unpack.err");
    }

    /*
     * Verify unpacked files.
     */

    /* Regular file with 2 links. */
    assertIsReg("file", 0644);
    failure("%s", from);
    assertFileSize("file", 10);
    assertFileSize("linkfile", 10);
    failure("%s", from);
    assertFileNLinks("file", 2);

    /* Another name for the same file. */
    failure("%s", from);
    assertIsHardlink("linkfile", "file");
    assertFileSize("file", 10);
    assertFileSize("linkfile", 10);

    /* Symlink */
    if (canSymlink())
        assertIsSymlink("symlink", "file");

    /* dir */
    assertIsDir("dir", 0775);

    assertChdir("..");
}

DEFINE_TEST(test_gcpio_compat)
{
    assertUmask(0);

    /* Dearchive sample files with a variety of options. */
    if (canSymlink()) {
        unpack_test("test_gcpio_compat_ref.bin",
            "--no-preserve-owner", "1 block\n");
        unpack_test("test_gcpio_compat_ref.crc",
            "--no-preserve-owner", "2 blocks\n");
        unpack_test("test_gcpio_compat_ref.newc",
            "--no-preserve-owner", "2 blocks\n");
        /* gcpio-2.9 only reads 6 blocks here */
        unpack_test("test_gcpio_compat_ref.ustar",
            "--no-preserve-owner", "7 blocks\n");
    } else {
        unpack_test("test_gcpio_compat_ref_nosym.bin",
            "--no-preserve-owner", "1 block\n");
        unpack_test("test_gcpio_compat_ref_nosym.crc",
            "--no-preserve-owner", "2 blocks\n");
        unpack_test("test_gcpio_compat_ref_nosym.newc",
            "--no-preserve-owner", "2 blocks\n");
        /* gcpio-2.9 only reads 6 blocks here */
        unpack_test("test_gcpio_compat_ref_nosym.ustar",
            "--no-preserve-owner", "7 blocks\n");
    }
}

--- NEW FILE: test_option_t.c ---
/*-
 * Copyright (c) 2003-2007 Tim Kientzle
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "test.h"
__FBSDID("$FreeBSD$");


DEFINE_TEST(test_option_t)
{
    char *p;
    int r;

    /* List reference archive, make sure the TOC is correct. */
    extract_reference_file("test_option_t.cpio");
    r = systemf("%s -it < test_option_t.cpio >it.out 2>it.err", testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "it.err");
    extract_reference_file("test_option_t.stdout");
    p = slurpfile(NULL, "test_option_t.stdout");
    assertTextFileContents(p, "it.out");
    free(p);

    /* We accept plain "-t" as a synonym for "-it" */
    r = systemf("%s -t < test_option_t.cpio >t.out 2>t.err", testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "t.err");
    extract_reference_file("test_option_t.stdout");
    p = slurpfile(NULL, "test_option_t.stdout");
    assertTextFileContents(p, "t.out");
    free(p);

    /* But "-ot" is an error. */
    assert(0 != systemf("%s -ot < test_option_t.cpio >ot.out 2>ot.err",
                testprog));
    assertEmptyFile("ot.out");

    /* List reference archive verbosely, make sure the TOC is correct. */
    r = systemf("%s -itv < test_option_t.cpio >tv.out 2>tv.err", testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "tv.err");
    extract_reference_file("test_option_tv.stdout");

    /* This doesn't work because the usernames on different systems
     * are different and cpio now looks up numeric UIDs on
     * the local system. */
    /* assertEqualFile("tv.out", "test_option_tv.stdout"); */

    /* List reference archive with numeric IDs, verify TOC is correct. */
    r = systemf("%s -itnv < test_option_t.cpio >itnv.out 2>itnv.err",
            testprog);
    assertEqualInt(r, 0);
    assertTextFileContents("1 block\n", "itnv.err");
    p = slurpfile(NULL, "itnv.out");
    /* Since -n uses numeric UID/GID, this part should be the
     * same on every system. */
    assertEqualMem(p, "-rw-r--r--   1 1000     1000            0 ",42);
    /* Date varies depending on local timezone. */
    if (memcmp(p + 42, "Dec 31  1969", 12) == 0) {
        /* East of Greenwich we get Dec 31, 1969. */
    } else {
        /* West of Greenwich get Jan 1, 1970 */
        assertEqualMem(p + 42, "Jan ", 4);
        /* Some systems format "Jan 01", some "Jan  1" */
        assert(p[46] == ' ' || p[46] == '0');
        assertEqualMem(p + 47, "1  1970 ", 8);
    }
    assertEqualMem(p + 54, " file", 5);
    free(p);

    /* But "-n" without "-t" is an error. */
    assert(0 != systemf("%s -in < test_option_t.cpio >in.out 2>in.err",
                testprog));
    assertEmptyFile("in.out");
}



More information about the Cmake-commits mailing list