Ejemplo n.º 1
0
static int ar_read_destroy(lua_State *L) {
    struct archive** self_ref = ar_read_check(L, 1);
    if ( NULL == *self_ref ) return 0;

    // If called in destructor, we were already removed from the weak
    // table, so we need to re-register so that the read callback
    // will work.
    ar_registry_set(L, *self_ref);

    if ( ARCHIVE_OK != archive_read_close(*self_ref) ) {
        lua_pushfstring(L, "archive_read_close: %s", archive_error_string(*self_ref));
        archive_read_finish(*self_ref);
        __ref_count--;
        *self_ref = NULL;
        lua_error(L);
    }

    ar_read_get_reader(L, 1); // {self}, reader
    if ( ! lua_isnil(L, -1) ) {
        lua_pushvalue(L, 1); // {self}, reader, {self}
        lua_pushnil(L); // {self}, reader, {self}, nil
        lua_call(L, 2, 1); // {self}, result
    }

    if ( ARCHIVE_OK != archive_read_finish(*self_ref) ) {
        luaL_error(L, "archive_read_finish: %s", archive_error_string(*self_ref));
    }
    __ref_count--;
    *self_ref = NULL;

    return 0;
}
Ejemplo n.º 2
0
//////////////////////////////////////////////////////////////////////
// Constructor:
static int ar_read(lua_State *L) {
    struct archive** self_ref;
    static named_setter format_names[] = {
        /* Copied from archive.h */
        { "all",       archive_read_support_format_all },
        { "ar",        archive_read_support_format_ar },
        { "cpio",      archive_read_support_format_cpio },
        { "empty",     archive_read_support_format_empty },
        { "gnutar",    archive_read_support_format_gnutar },
        { "iso9660",   archive_read_support_format_iso9660 },
        { "mtree",     archive_read_support_format_mtree },
        { "tar",       archive_read_support_format_tar },
        { "zip",       archive_read_support_format_zip },
        { NULL,        NULL }
    };
    static named_setter compression_names[] = {
        { "all",      archive_read_support_compression_all },
        { "bzip2",    archive_read_support_compression_bzip2 },
        { "compress", archive_read_support_compression_compress },
        { "gzip",     archive_read_support_compression_gzip },
        { "lzma",     archive_read_support_compression_lzma },
        { "none",     archive_read_support_compression_none },
        { "xz",       archive_read_support_compression_xz },
        { NULL,       NULL }
    };

    luaL_checktype(L, 1, LUA_TTABLE);

    self_ref = (struct archive**)
        lua_newuserdata(L, sizeof(struct archive*)); // {ud}
    *self_ref = NULL;
    luaL_getmetatable(L, AR_READ); // {ud}, [read]
    lua_setmetatable(L, -2); // {ud}
    __ref_count++;
    *self_ref = archive_read_new();

    // Register it in the weak metatable:
    ar_registry_set(L, *self_ref);

    // Create an environment to store a reference to the callbacks:
    lua_createtable(L, 1, 0); // {ud}, {fenv}
    lua_getfield(L, 1, "reader"); // {ud}, {fenv}, fn
    if ( ! lua_isfunction(L, -1) ) err("MissingArgument: required parameter 'reader' must be a function");
    lua_setfield(L, -2, "reader"); // {ud}, {fenv}
    lua_setfenv(L, -2); // {ud}

    // Do it the easy way for now... perhaps in the future we will
    // have a parameter to support toggling which algorithms are
    // supported:
    if ( ARCHIVE_OK != archive_read_support_compression_all(*self_ref) ) {
        err("archive_read_support_compression_all: %s", archive_error_string(*self_ref));
    }
    if ( ARCHIVE_OK != archive_read_support_format_all(*self_ref) ) {
        err("archive_read_support_format_all: %s", archive_error_string(*self_ref));
    }


    // Extract various fields and prepare the archive:
    lua_getfield(L, 1, "format");
    if ( NULL == lua_tostring(L, -1) ) {
        lua_pop(L, 1);
        lua_pushliteral(L, "all");
    }
    if ( 0 == call_setters(L,
                           *self_ref,
                           "archive_read_support_format_",
                           format_names,
                           lua_tostring(L, -1)) )
    {
        // We will be strict for now... perhaps in the future we will
        // default to "all"?
        err("empty format='%s' is not allowed, you must specify at least one format",
            lua_tostring(L, -1));
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "compression");
    if ( NULL == lua_tostring(L, -1) ) {
        lua_pop(L, 1);
        lua_pushliteral(L, "none");
    }
    call_setters(L, 
                 *self_ref,
                 "archive_read_support_compression_",
                 compression_names,
                 lua_tostring(L, -1));
    lua_pop(L, 1);

    lua_getfield(L, 1, "options");
    if ( ! lua_isnil(L, -1) &&
         ARCHIVE_OK != archive_read_set_options(*self_ref, lua_tostring(L, -1)) )
    {
        err("archive_read_set_options: %s",  archive_error_string(*self_ref));
    }
    lua_pop(L, 1);


    if ( ARCHIVE_OK != archive_read_open(*self_ref, L, NULL, &ar_read_cb, NULL) ) {
        err("archive_read_open: %s", archive_error_string(*self_ref));
    }

    return 1;
}
Ejemplo n.º 3
0
//////////////////////////////////////////////////////////////////////
// Constructor:
static int ar_write(lua_State *L) {
    struct archive** self_ref;

    static struct {
        const char *name;
        int (*setter)(struct archive *);
    } names[] = {
        /* Copied from archive_write_set_format_by_name.c */
        { "ar",         archive_write_set_format_ar_bsd },
        { "arbsd",      archive_write_set_format_ar_bsd },
        { "argnu",      archive_write_set_format_ar_svr4 },
        { "arsvr4",     archive_write_set_format_ar_svr4 },
        { "cpio",       archive_write_set_format_cpio },
        { "mtree",      archive_write_set_format_mtree },
        { "newc",       archive_write_set_format_cpio_newc },
        { "odc",        archive_write_set_format_cpio },
        { "pax",        archive_write_set_format_pax },
        { "posix",      archive_write_set_format_pax },
        { "shar",       archive_write_set_format_shar },
        { "shardump",   archive_write_set_format_shar_dump },
        { "ustar",      archive_write_set_format_ustar },
        /* New ones to more closely match the C API */
        { "ar_bsd",     archive_write_set_format_ar_bsd },
        { "ar_svr4",    archive_write_set_format_ar_svr4 },
        { "cpio_newc",  archive_write_set_format_cpio_newc },
        { "pax_restricted", archive_write_set_format_pax_restricted },
        { "shar_dump",  archive_write_set_format_shar_dump },
        { NULL,         NULL }
    };
    int idx = 0;
    const char* name;

    luaL_checktype(L, 1, LUA_TTABLE);
    self_ref = (struct archive**)
        lua_newuserdata(L, sizeof(struct archive*)); // {ud}
    luaL_getmetatable(L, AR_WRITE); // {ud}, [write]
    lua_setmetatable(L, -2); // {ud}
    __ref_count++;
    *self_ref = archive_write_new();

    // Register it in the weak metatable:
    ar_registry_set(L, *self_ref);

    // Create an environment to store a reference to the writer:
    lua_createtable(L, 1, 0); // {ud}, {}
    lua_pushliteral(L, "writer"); // {ud}, {}, "writer"
    lua_rawget(L, 1); // {ud}, {}, fn
    if ( ! lua_isfunction(L, -1) ) {
        err("MissingArgument: required parameter 'writer' must be a function");
    }
    lua_setfield(L, -2, "writer");
    lua_setfenv(L, -2); // {ud}

    // Extract various fields and prepare the archive:
    lua_getfield(L, 1, "bytes_per_block");
    if ( ! lua_isnil(L, -1) &&
         ARCHIVE_OK != archive_write_set_bytes_per_block(*self_ref, lua_tointeger(L, -1)) )
    {
        err("archive_write_set_bytes_per_block: %s", archive_error_string(*self_ref));
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "bytes_in_last_block");
    if ( ! lua_isnil(L, -1) &&
         ARCHIVE_OK != archive_write_set_bytes_in_last_block(*self_ref, lua_tointeger(L, -1)) )
    {
        err("archive_write_set_bytes_in_last_block: %s", archive_error_string(*self_ref));
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "skip_file");
    if ( ! lua_isnil(L, -1) ) {
        dev_t dev;
        ino_t ino;

        if ( LUA_TTABLE != lua_type(L, -1) ) {
            err("skip_file member must be a table object");
        }

        lua_getfield(L, -1, "dev");
        if ( ! lua_isnumber(L, -1) ) {
            err("skip_file.dev member must be a number");
        }
        dev = (dev_t)lua_tonumber(L, -1);
        lua_pop(L, 1);

        lua_getfield(L, -1, "ino");
        if ( ! lua_isnumber(L, -1) ) {
            err("skip_file.ino member must be a number");
        }
        ino = (ino_t)lua_tonumber(L, -1);
        lua_pop(L, 1);

        if ( ARCHIVE_OK != archive_write_set_skip_file(*self_ref, dev, ino) ) {
            err("archive_write_set_skip_file: %s", archive_error_string(*self_ref));
        }
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "format");
    if ( lua_isnil(L, -1) ) {
        lua_pop(L, 1);
        lua_pushliteral(L, "posix");
    }
    name = lua_tostring(L, -1);
    for ( ;; idx++ ) {
        if ( names[idx].name == NULL ) {
            err("archive_write_set_format_*: No such format '%s'", name);
        }
        if ( strcmp(name, names[idx].name) == 0 ) break;
    }
    if ( ARCHIVE_OK != (names[idx].setter)(*self_ref) ) {
        err("archive_write_set_format_%s: %s", name, archive_error_string(*self_ref));
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "compression");
    if ( ! lua_isnil(L, -1) ) {
        static struct {
            const char *name;
            int (*setter)(struct archive *);
        } names[] = {
            { "bzip2",    archive_write_add_filter_bzip2 },
            { "compress", archive_write_add_filter_compress },
            { "gzip",     archive_write_add_filter_gzip },
            { "lzma",     archive_write_add_filter_lzma },
            { "xz",       archive_write_add_filter_xz },
            { NULL,       NULL }
        };
        int idx = 0;
        const char* name = lua_tostring(L, -1);
        for ( ;; idx++ ) {
            if ( names[idx].name == NULL ) {
                err("archive_write_set_compression_*: No such compression '%s'", name);
            }
            if ( strcmp(name, names[idx].name) == 0 ) break;
        }
        if ( ARCHIVE_OK != (names[idx].setter)(*self_ref) ) {
            err("archive_write_set_compression_%s: %s", name, archive_error_string(*self_ref));
        }
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "options");
    if ( ! lua_isnil(L, -1) &&
         ARCHIVE_OK != archive_write_set_options(*self_ref, lua_tostring(L, -1)) )
    {
        err("archive_write_set_options: %s",  archive_error_string(*self_ref));
    }
    lua_pop(L, 1);


    if ( ARCHIVE_OK != archive_write_open(*self_ref, L, NULL, &ar_write_cb, NULL) ) {
        err("archive_write_open: %s", archive_error_string(*self_ref));
    }

    return 1;
}