zip_int64_t
_zip_replace(struct zip *za, zip_uint64_t idx, const char *name,
	     struct zip_source *source)
{
    zip_uint64_t za_nentry_prev;
    if (ZIP_IS_RDONLY(za)) {
	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
	return -1;
    }

    za_nentry_prev = za->nentry;
    if (idx == ZIP_UINT64_MAX) {
	if (_zip_entry_new(za) == NULL)
	    return -1;
	
	idx = za->nentry - 1;
	za->entry[idx].changes.valid |= ZIP_DIRENT_COMP_METHOD;
	za->entry[idx].changes.comp_method = ZIP_CM_DEFLATE; /* XXX: default */
    }
    
    if (name && _zip_set_name(za, idx, name) != 0) {
	za->nentry = za_nentry_prev;
	return -1;
    }

    /* does not change any name related data, so we can do it here;
     * needed for a double add of the same file name */
    _zip_unchange_data(za->entry+idx);

    za->entry[idx].state = ((za->cdir == NULL || idx >= (zip_uint64_t)za->cdir->nentry)
			    ? ZIP_ST_ADDED : ZIP_ST_REPLACED);
    za->entry[idx].source = source;

    return idx;
}
Exemplo n.º 2
0
struct zip *
_zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep)
{
    struct zip *za;
    struct zip_cdir *cdir;
    int i;
    off_t len;

    if (fseeko(fp, 0, SEEK_END) < 0) {
	*zep = ZIP_ER_SEEK;
	return NULL;
    }
    len = ftello(fp);

    /* treat empty files as empty archives */
    if (len == 0) {
	if ((za=_zip_allocate_new(fn, zep)) == NULL)
	    fclose(fp);
	else
	    za->zp = fp;
	return za;
    }

    cdir = _zip_find_central_dir(fp, flags, zep, len);
    if (cdir == NULL) {
	fclose(fp);
	return NULL;
    }

    if ((za=_zip_allocate_new(fn, zep)) == NULL) {
	_zip_cdir_free(cdir);
	fclose(fp);
	return NULL;
    }

    za->cdir = cdir;
    za->zp = fp;

    if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry))
					      * cdir->nentry)) == NULL) {
	set_error(zep, NULL, ZIP_ER_MEMORY);
	_zip_free(za);
	return NULL;
    }
    for (i=0; i<cdir->nentry; i++)
	_zip_entry_new(za);

    _zip_check_torrentzip(za);
    za->ch_flags = za->flags;

    return za;
}
Exemplo n.º 3
0
ZIP_EXTERN struct zip *
zip_open(const char *fn, int flags, int *zep)
{
    FILE *fp;
    struct zip *za;
    struct zip_cdir *cdir;
    int i;
    off_t len;
    
    switch (_zip_file_exists(fn, flags, zep)) {
    case -1:
	return NULL;
    case 0:
	return _zip_allocate_new(fn, zep);
    default:
	break;
    }

    if ((fp=fopen(fn, "rb")) == NULL) {
	set_error(zep, NULL, ZIP_ER_OPEN);
	return NULL;
    }

    fseeko(fp, 0, SEEK_END);
    len = ftello(fp);

    /* treat empty files as empty archives */
    if (len == 0) {
	if ((za=_zip_allocate_new(fn, zep)) == NULL)
	    fclose(fp);
	else
	    za->zp = fp;
	return za;
    }

    cdir = _zip_find_central_dir(fp, flags, zep, len);
    if (cdir == NULL) {
	fclose(fp);
	return NULL;
    }

    if ((za=_zip_allocate_new(fn, zep)) == NULL) {
	_zip_cdir_free(cdir);
	fclose(fp);
	return NULL;
    }

    za->cdir = cdir;
    za->zp = fp;

    if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry))
					      * cdir->nentry)) == NULL) {
	set_error(zep, NULL, ZIP_ER_MEMORY);
	_zip_free(za);
	return NULL;
    }
    for (i=0; i<cdir->nentry; i++)
	_zip_entry_new(za);

    _zip_check_torrentzip(za);
    za->ch_flags = za->flags;

    return za;
}