Beispiel #1
0
static int Lreader_locate_file(lua_State *L) {
    mz_zip_archive *za = luaL_checkudata(L, 1, LMZ_ZIP_READER);
    const char *path = luaL_checkstring(L, 2);
    mz_uint32 flags = (mz_uint32)luaL_optinteger(L, 3, 0);
    int index = mz_zip_reader_locate_file(za, path, NULL, flags);
    if (index < 0) return lmz_zip_pusherror(L, za, path);
    lua_pushinteger(L, index + 1);
    return 1;
}
Beispiel #2
0
static int lmz_reader_locate_file(lua_State *L) {
  lmz_file_t* zip = luaL_checkudata(L, 1, "miniz_reader");
  const char *path = luaL_checkstring(L, 2);
  mz_uint32 flags = luaL_optint(L, 3, 0);
  int index = mz_zip_reader_locate_file(&(zip->archive), path, NULL, flags);
  if (index < 0) {
    lua_pushnil(L);
    lua_pushfstring(L, "Can't find file %s.", path);
    return 2;
  }
  lua_pushinteger(L, index + 1);
  return 1;
}
Beispiel #3
0
	// open archived file
	bool ZipIO::openFile(const std::string &FileName){
		_kfname = "";
		_kready = false;
		if (!_kisopen)
			return false;

		// file is ready for writing
		if (_kmode == OpenMode::WRITE || _kmode == OpenMode::APPEND) {
			_kfname = FileName;
			_kready = true;
			return true;
		}

		// check for reading
		if ((_kfindex = mz_zip_reader_locate_file(&_kzarchive, FileName.c_str(), NULL, 0)) < 0)
			return false;

		return openFile(_kfindex);
	}
adapt_serving_context* adapt_start_serving(adapt_callback* callback) {
    int tries;
    int file_index;
    char* rewrites = 0;
    char* document_root = 0;
    adapt_serving_context* context = (adapt_serving_context*)calloc(sizeof(adapt_serving_context), 1);
    time_t timeval;
    adapt_resource_init();
    time(&timeval);
    sprintf(context->content_prefix, "/E%lx/", timeval);
    sprintf(context->html_prefix, "/H%lx/", timeval);
    sprintf(context->msg_url, "/M%lx", timeval);
    context->callback = callback;
    if (callback->packaging_type == ADAPT_PACKAGE_ZIP) {
        context->zip.m_pRead = adapt_file_read_func;
        context->zip.m_pIO_opaque = callback;
        if (!mz_zip_reader_init(&context->zip, callback->content_length, MZ_ZIP_FLAG_CASE_SENSITIVE)) {
            free(context);
            return NULL;
        }
        // Check if this is an epub file.
        file_index = mz_zip_reader_locate_file(&context->zip, "META-INF/container.xml", NULL,
                                               MZ_ZIP_FLAG_CASE_SENSITIVE);
        context->content_type = TYPE_UNKNOWN;
        if (file_index >= 0) {
            // This looks like epub
            context->content_type = TYPE_OPF;
        } else {
            // This is not an epub. Maybe fb2.zip?
            mz_zip_archive_file_stat file_info;
            if (mz_zip_reader_file_stat(&context->zip, 0, &file_info)) {
                const char* filename = file_info.m_filename;
                size_t len = strlen(filename);
                if (len > 4 && strcmp(filename + len - 4, ".fb2") == 0) {
                    // This is FB2 file
                    context->content_type = TYPE_XML;
                    context->content = strcpy((char*)malloc(strlen(filename) + 1), filename);
                }
            }
        }
    } else if (callback->packaging_type == ADAPT_PACKAGE_FILE_SYSTEM) {
        size_t len;
        char* container_name;
        char* end;
        if (!callback->base_path) {
            free(context);
            return NULL;
        }
        // Go through the parent folder chain trying to find META-INF/container.xml (that will serve as
        // the package root)
        len = strlen(callback->base_path);
        container_name = (char*)malloc(len + 25);
        strcpy(container_name, callback->base_path);
        end = container_name + len;
        do {
            char * q = end - 1;
            while (container_name + 3 < q && *q != '/') {
                q--;
            }
            if (*q != '/') {
                break;
            }
            end = q;
            strcpy(end + 1, "META-INF/container.xml");
        } while (!file_exists(container_name));
        if (*end != '/') {
            free(context);
            return NULL;
        }
        if (len < 4 || strcmp(callback->base_path + len - 4, ".opf") == 0) {
            context->content_type = TYPE_OPF;
        } else {
            size_t prefix_len = (end - container_name + 1);
            const char* path = callback->base_path + prefix_len;
            context->content = strcpy((char*)malloc(strlen(path) + 1), path);
            context->content_type = TYPE_XML;
            context->prefix_len = prefix_len;
        }
        end[1] = '\0';
        rewrites = (char*)malloc(strlen(container_name) + strlen(context->content_prefix) + 2);
        sprintf(rewrites, "%s=%s", context->content_prefix, container_name);
        document_root = container_name;
    } else if (callback->packaging_type == ADAPT_PACKAGE_SINGLE_FILE) {
        // Assume it's FB2
        context->content_type = TYPE_XML;
        context->content = strcpy((char*)malloc(9), "file.fb2");
    }
    if (context->content_type == TYPE_UNKNOWN) {
        adapt_stop_serving(context);
        return NULL;
    }
    context->server_callbacks.begin_request = adapt_serve;
    context->options = (char**)calloc(sizeof(char*), 7);
    context->options[0] = strcpy((char*)malloc(16), "listening_ports");
    context->options[1] = (char*)calloc(100, 1);
    if (rewrites) {
        context->options[2] = strcpy((char*)malloc(24), "url_rewrite_patterns");
        context->options[3] = rewrites;
        context->options[4] = strcpy((char*)malloc(24), "document_root");
        context->options[5] = document_root;
    }
    tries = 0;
    do {
        sprintf(context->options[1], "127.0.0.1:%d", adapt_port);
        context->server_context = mg_start(&context->server_callbacks, context, (const char**)context->options);
        sprintf(context->bootstrap_url, "http://127.0.0.1:%d%sdriver.xhtml",
                adapt_port, context->html_prefix);
        adapt_port++;
        tries++;
    } while (!context->server_context && tries < 10);
    return context;
}
static int adapt_serve_zip_metadata(const char* method, struct mg_connection* connection,
                                    adapt_serving_context* context, const char* item) {
    if (strcmp(item, "list") == 0 && strcmp(method, "GET") == 0) {
        // URL-encoding may turn one character into three.
        char name_buffer[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE * 3 + 4];
        int file_index = 0;
        mz_zip_archive_file_stat file_info;
        const char* sep = "";
        mg_printf(connection,
                  "HTTP/1.1 200 Success\r\n"
                  "Content-Type: text/plain\r\n"
                  "\r\n[");
        while (mz_zip_reader_file_stat(&context->zip, file_index, &file_info)) {
            ++file_index;
            url_encode_name(file_info.m_filename, name_buffer, sizeof name_buffer);
            mg_printf(connection, "%s{\"n\":\"%s\",\"m\":%d,\"c\":%llu,\"u\":%llu}",
                      sep, name_buffer, file_info.m_method, file_info.m_comp_size, file_info.m_uncomp_size);
            sep = ",";
        }
        mg_printf(connection, "]\r\n");
        return 1;
    } else if (strcmp(item, "manifest") == 0 && strcmp(method, "POST") == 0) {
        char file_name[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE+1];
        int len = 0;
        char* buf = adapt_read_connection(connection, &len);
        if (buf) {
            char* s = buf;
            int file_index;
            if (!context->file_info) {
                int file_count = mz_zip_reader_get_num_files(&context->zip);
                context->file_info = (struct adapt_file_info*)calloc(sizeof(struct adapt_file_info), file_count);
            }
            while (1) {
                char* url = s;
                char* media_type;
                char* obfuscation_str = NULL;
                s = strpbrk(s, " \n");
                if (!s) {
                    break;
                }
                if (*s == '\n') {
                    continue;
                }
                *s = '\0';
                s++;
                url_decode_name(url, file_name, sizeof file_name);
                media_type = s;
                s = strpbrk(s, " \n");
                if (!s) {
                    break;
                }
                if (*s == ' ') {
                    /* Have obfuscation data */
                    *s = '\0';
                    s++;
                    obfuscation_str = s;
                    s = strpbrk(s, " \n");
                    if (!s) {
                        break;
                    }
                    if (*s != '\n') {
                        /* Need to reach end of line */
                        *s = '\0';
                        s = strchr(s, '\n');
                        if (!s) {
                            break;
                        }
                    }
                }
                *s = '\0';
                s++;
                file_index = mz_zip_reader_locate_file(&context->zip, file_name, NULL,
                                                       MZ_ZIP_FLAG_CASE_SENSITIVE);
                if (file_index >= 0) {
                    struct adapt_file_info* file_info = &context->file_info[file_index];
                    adapt_file_info_clear(file_info);
                    file_info->media_type = strcpy((char *)malloc(strlen(media_type) + 1), media_type);
                    if (obfuscation_str) {
                        char* sep = strchr(obfuscation_str, ':');
                        if (sep) {
                            unsigned int length;
                            *sep = '\0';
                            length = atoi(obfuscation_str);
                            if (length < 2048) { /* Sanity check */
                                char* mask_hex = sep + 1;
                                size_t mask_hex_length = strlen(mask_hex);
                                if (mask_hex_length % 2 == 0 && mask_hex_length <= 128) { /* Sanity check */
                                    unsigned int k;
                                    struct adapt_obfuscation* obfuscation =
                                        (struct adapt_obfuscation*)calloc(sizeof(struct adapt_obfuscation), 1);
                                    obfuscation->length = length;
                                    obfuscation->mask_length = (unsigned int)(mask_hex_length / 2);
                                    obfuscation->mask = (unsigned char *)calloc(1, obfuscation->mask_length);
                                    for (k = 0; k < mask_hex_length; k += 2) {
                                        char t[] = {mask_hex[k], mask_hex[k+1], '\0'};
                                        obfuscation->mask[k/2] = (unsigned char)strtol(t, NULL, 16);
                                    }
                                    file_info->obfuscation = obfuscation;
                                }
                            }
                        }
                    }
                }
            }
            free(buf);
        }
    }
    return 0;
}
static int adapt_serve_zip_entry(struct mg_connection* connection, adapt_serving_context* context,
                                 const char* file_name) {
    int file_index = mz_zip_reader_locate_file(&context->zip, file_name, NULL,
                     MZ_ZIP_FLAG_CASE_SENSITIVE);
    mz_zip_archive_file_stat file_info;
    if (mz_zip_reader_file_stat(&context->zip, file_index, &file_info)) {
        if (file_index >= 0) {
            // Possible filters
            struct adapt_sink_connection sink_connection;
            struct adapt_sink_safari_bug filter_safari_bug;
            struct adapt_sink_deobfuscate filter_deobfuscate;
            struct adapt_sink_inflator filter_inflator;
            struct adapt_sink_woff filter_woff;
            // Build filter chain.
            char* media_type = context->file_info ? context->file_info[file_index].media_type : NULL;
            struct adapt_sink* sink = &sink_connection.super;
            int known_length = 1;
            int flush = 0;
            sink_connection.super.write = adapt_sink_connection_write;
            sink_connection.connection = connection;
            if (media_type && strcmp(media_type, "application/xhtml+xml") == 0) {
                filter_safari_bug.super.write = adapt_sink_safari_bug_write;
                filter_safari_bug.state = 1;
                filter_safari_bug.next = sink;
                sink = &filter_safari_bug.super;
            } else if (media_type && adapt_convert_to_woff &&
                       (strcmp(media_type, "application/x-font-truetype") == 0
                        || strcmp(media_type, "application/x-font-opentype") == 0
                        || strcmp(media_type, "application/vnd.ms-opentype") == 0
                        || strcmp(media_type, "font/truetype") == 0
                        || strcmp(media_type, "font/opentype") == 0)) {
                filter_woff.buffer = NULL;
                filter_woff.buffer_size = 0;
                filter_woff.buffer_used = 0;
                filter_woff.super.write = adapt_sink_woff_write;
                filter_woff.next = sink;
                sink = &filter_woff.super;
                known_length = 0;
                flush = 1;
            }
            if (context->file_info && context->file_info[file_index].obfuscation) {
                if (file_info.m_method == 0) {
                    /* Stored and obfuscated: obfuscation applied after deflate. */
                    filter_inflator.super.write = adapt_sink_inflator_write;
                    tinfl_init(&filter_inflator.inflator);
                    filter_inflator.inflated_file_offset = 0;
                    filter_inflator.buffer_offset = 0;
                    filter_inflator.next = sink;
                    sink = &filter_inflator.super;
                    known_length = 0;
                    flush = 1;
                }
                filter_deobfuscate.super.write = adapt_sink_deobfuscate_write;
                filter_deobfuscate.obfuscation = context->file_info[file_index].obfuscation;
                filter_deobfuscate.next = sink;
                sink = &filter_deobfuscate.super;
            }
            mg_printf(connection, "HTTP/1.1 200 Success\r\n");
            if (known_length) {
                mg_printf(connection, "Content-Length: %d\r\n", (int)file_info.m_uncomp_size);
            }
            if (media_type) {
                mg_printf(connection,
                          "Content-Type: %s\r\n\r\n",
                          media_type);
            } else {
                mg_printf(connection, "\r\n");
            }
            mz_zip_reader_extract_to_callback(&context->zip, file_index,
                                              adapt_sink_write, sink, MZ_ZIP_FLAG_CASE_SENSITIVE);
            if (flush) {
                sink->write(sink, (size_t)file_info.m_uncomp_size, NULL, 0);
            }
            return 1;
        }
        mg_printf(connection,
                  "HTTP/1.1 404 Not found\r\n"
                  "Content-Length: 0\r\n"
                  "\r\n");
        return 1;
    }
    return 0;
}
Beispiel #7
0
bool fe_zip_open_to_buff(
	const char *archive,
	const char *filename,
	FE_ZIP_ALLOC_CALLBACK callback,
	void **buff,
	size_t *buff_size )
{
	ASSERT( buff != NULL );

	mz_zip_archive zip;
	memset( &zip, 0, sizeof( zip ) );

	if ( !mz_zip_reader_init_file( &zip, archive, 0 ) )
	{
		std::cerr << "Error initializing zip.  zip: "
			<< archive << std::endl;
		return false;
	}

	int index = mz_zip_reader_locate_file( &zip,
		filename, NULL, 0 );
	if ( index < 0 )
	{
		std::cerr << "Error locating file. zip: "
			<< archive << ", file: " << filename << std::endl;
		mz_zip_reader_end( &zip );
		return false;
	}

	mz_zip_archive_file_stat file_stat;
	if ( !mz_zip_reader_file_stat(&zip, index, &file_stat) )
	{
		std::cerr << "Error reading filestats. zip: "
			<< archive << ", file: " << filename << std::endl;
		mz_zip_reader_end( &zip );
		return false;
	}

	void *tb = callback( file_stat.m_uncomp_size );

	if ( tb == NULL )
	{
		std::cerr << "Error allocating zip buffer. zip: "
			<< archive << ", file: " << filename << std::endl;
		mz_zip_reader_end( &zip );
		return false;
	}

	if ( !mz_zip_reader_extract_to_mem( &zip,
		index, tb, file_stat.m_uncomp_size, 0 ) )
	{
		std::cerr << "Error extracting to buffer. zip: "
			<< archive << ", file: " << filename << std::endl;
		mz_zip_reader_end( &zip );

		delete (char *)tb;
		return false;
	}

	mz_zip_reader_end( &zip );

	*buff = tb;

	if ( buff_size )
		*buff_size = file_stat.m_uncomp_size;

	return true;
}
Beispiel #8
0
	I32 ZipIO::searchFile(const std::string &FileName){
		if (!_kisopen || _kmode == OpenMode::WRITE)
			return -1;

		return mz_zip_reader_locate_file(&_kzarchive, FileName.c_str(), NULL, 0);
	}