Esempio n. 1
0
void
_zip_entry_finalize(struct zip_entry *e)
{
    _zip_unchange_data(e);
    _zip_dirent_free(e->orig);
    _zip_dirent_free(e->changes);
}
int
_zip_unchange(struct zip *za, zip_uint64_t idx, int allow_duplicates)
{
    zip_int64_t i;

    if (idx >= za->nentry) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
    }

    if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) {
        i = _zip_name_locate(za, _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), 0, NULL);
        if (i >= 0 && (zip_uint64_t)i != idx) {
            _zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
            return -1;
        }
    }

    _zip_dirent_free(za->entry[idx].changes);
    za->entry[idx].changes = NULL;

    _zip_unchange_data(za->entry+idx);

    return 0;
}
Esempio n. 3
0
ZIP_EXTERN int
zip_set_file_compression(struct zip *za, zip_uint64_t idx,
			 zip_int32_t method, zip_uint32_t flags)
{
    struct zip_entry *e;
	zip_int32_t old_method;

    if (idx >= za->nentry) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if (ZIP_IS_RDONLY(za)) {
	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
	return -1;
    }

    if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) {
	_zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
	return -1;
    }

    e = za->entry+idx;
    
    //zip_int32_t old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method);
    old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method);
    
    /* XXX: revisit this when flags are supported, since they may require a recompression */
    
    if (method == old_method) {
	if (e->changes) {
	    e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD;
	    if (e->changes->changed == 0) {
		_zip_dirent_free(e->changes);
		e->changes = NULL;
	    }
	}
    }
    else {
        if (e->changes == NULL) {
            if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return -1;
            }
        }

        e->changes->comp_method = method;
        e->changes->changed |= ZIP_DIRENT_COMP_METHOD;
    }
    
    return 0;
}
int
zip_file_set_external_attributes(struct zip *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t opsys, zip_uint32_t attributes)
{
    struct zip_entry *e;
    int changed;
    zip_uint8_t unchanged_opsys;
    zip_uint32_t unchanged_attributes;

    if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
	return -1;

    if (ZIP_IS_RDONLY(za)) {
	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
	return -1;
    }

    e = za->entry+idx;

    unchanged_opsys = e->orig ? e->orig->version_madeby>>8 : ZIP_OPSYS_DEFAULT;
    unchanged_attributes = e->orig ? e->orig->ext_attrib : ZIP_EXT_ATTRIB_DEFAULT;

    changed = (opsys != unchanged_opsys || attributes != unchanged_attributes);

    if (changed) {
        if (e->changes == NULL) {
            if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return -1;
            }
        }
        e->changes->version_madeby = (opsys << 8) | (e->changes->version_madeby & 0xff);
	e->changes->ext_attrib = attributes;
        e->changes->changed |= ZIP_DIRENT_ATTRIBUTES;
    }
    else if (e->changes) {
	e->changes->changed &= ~ZIP_DIRENT_ATTRIBUTES;
	if (e->changes->changed == 0) {
	    _zip_dirent_free(e->changes);
	    e->changes = NULL;
	}
	else {
	    e->changes->version_madeby = (unchanged_opsys << 8) | (e->changes->version_madeby & 0xff);
	    e->changes->ext_attrib = unchanged_attributes;
	}
    }

    return 0;
}
Esempio n. 5
0
void
_zip_unchange_data(zip_entry_t *ze)
{
    if (ze->source) {
	zip_source_free(ze->source);
	ze->source = NULL;
    }

    if (ze->changes != NULL && (ze->changes->changed & ZIP_DIRENT_COMP_METHOD) && ze->changes->comp_method == ZIP_CM_REPLACED_DEFAULT) {
	ze->changes->changed &= ~ZIP_DIRENT_COMP_METHOD;
	if (ze->changes->changed == 0) {
	    _zip_dirent_free(ze->changes);
	    ze->changes = NULL;
	}
    }

    ze->deleted = 0;
}
Esempio n. 6
0
ZIP_EXTERN int zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
{
    zip_entry_t *e;
    int changed;

    if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
        return -1;

    if (ZIP_IS_RDONLY(za)) {
        zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
        return -1;
    }

    e = za->entry+idx;

    changed = e->orig == NULL || mtime != e->orig->last_mod;

    if (changed) {
        if (e->changes == NULL) {
            if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
                zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return -1;
            }
        }
        e->changes->last_mod = mtime;
        e->changes->changed |= ZIP_DIRENT_LAST_MOD;
    }
    else {
        if (e->changes) {
            e->changes->changed &= ~ZIP_DIRENT_LAST_MOD;
            if (e->changes->changed == 0) {
		_zip_dirent_free(e->changes);
                e->changes = NULL;
            }
        }
    }

    return 0;
}
Esempio n. 7
0
int
_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
{
    struct zip_entry *e;
    struct zip_string *str;
    int changed;
    zip_int64_t i;

    if (idx >= za->nentry) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
    }

    if (ZIP_IS_RDONLY(za)) {
        _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
        return -1;
    }

    if (name && strlen(name) > 0) {
        /* XXX: check for string too long */
        if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL)
            return -1;
        if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
            str->encoding = ZIP_ENCODING_UTF8_KNOWN;
    }
    else
        str = NULL;

    /* XXX: encoding flags needed for CP437? */
    if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) {
        _zip_string_free(str);
        _zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
        return -1;
    }

    /* no effective name change */
    if (i>=0 && (zip_uint64_t)i == idx) {
        _zip_string_free(str);
        return 0;
    }

    e = za->entry+idx;

    if (e->changes) {
        _zip_string_free(e->changes->filename);
        e->changes->filename = NULL;
        e->changes->changed &= ~ZIP_DIRENT_FILENAME;
    }

    if (e->orig)
        changed = !_zip_string_equal(e->orig->filename, str);
    else
        changed = 1;

    if (changed) {
        if (e->changes == NULL) {
            if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return -1;
            }
        }
        e->changes->filename = str;
        e->changes->changed |= ZIP_DIRENT_FILENAME;
    }
    else {
        _zip_string_free(str);
        if (e->changes && e->changes->changed == 0) {
            _zip_dirent_free(e->changes);
            e->changes = NULL;
        }
    }

    return 0;
}
Esempio n. 8
0
ZIP_EXTERN int
zip_file_set_comment(struct zip *za, zip_uint64_t idx,
		     const char *comment, zip_uint16_t len, zip_flags_t flags)
{
    struct zip_entry *e;
    struct zip_string *cstr;
    struct zip_dirent *de;
    int changed;

    if ((de=_zip_get_dirent(za, idx, 0, NULL)) == NULL)
	return -1;

    if (ZIP_IS_RDONLY(za)) {
	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
	return -1;
    }

    if (len > 0 && comment == NULL) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if (len > 0) {
	if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL)
	    return -1;
	if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
	    cstr->encoding = ZIP_ENCODING_UTF8_KNOWN;
    }
    else
	cstr = NULL;

    e = za->entry+idx;

    if (e->changes) {
	_zip_string_free(e->changes->comment);
	e->changes->comment = NULL;
	e->changes->changed &= ~ZIP_DIRENT_COMMENT;
    }

    if (e->orig && e->orig->comment)
	changed = !_zip_string_equal(e->orig->comment, cstr);
    else
	changed = (cstr != NULL);
	
    if (changed) {
        if (e->changes == NULL) {
            if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return -1;
            }
        }
        e->changes->comment = cstr;
        e->changes->changed |= ZIP_DIRENT_COMMENT;
    }
    else {
	_zip_string_free(cstr);
	if (e->changes && e->changes->changed == 0) {
	    _zip_dirent_free(e->changes);
	    e->changes = NULL;
	}
    }

    return 0;
}
Esempio n. 9
0
int
_zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
{
    zip_entry_t *e;
    zip_string_t *str;
    bool same_as_orig;
    zip_int64_t i;
    const zip_uint8_t *old_name, *new_name;
    zip_string_t *old_str;

    if (idx >= za->nentry) {
	zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if (ZIP_IS_RDONLY(za)) {
	zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
	return -1;
    }

    if (name && name[0] != '\0') {
        /* TODO: check for string too long */
	if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL)
	    return -1;
	if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
	    str->encoding = ZIP_ENCODING_UTF8_KNOWN;
    }
    else
	str = NULL;

    /* TODO: encoding flags needed for CP437? */
    if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) {
	_zip_string_free(str);
	zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
	return -1;
    }

    /* no effective name change */
    if (i>=0 && (zip_uint64_t)i == idx) {
	_zip_string_free(str);
	return 0;
    }

    e = za->entry+idx;

    if (e->orig)
	same_as_orig = _zip_string_equal(e->orig->filename, str);
    else
	same_as_orig = false;

    if (!same_as_orig && e->changes == NULL) {
	if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
	    zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    _zip_string_free(str);
	    return -1;
	}
    }

    if ((new_name = _zip_string_get(same_as_orig ? e->orig->filename : str, NULL, 0, &za->error)) == NULL) {
	_zip_string_free(str);
	return -1;
    }

    if (e->changes) {
	old_str = e->changes->filename;
    }
    else if (e->orig) {
	old_str = e->orig->filename;
    }
    else {
	old_str = NULL;
    }
    
    if (old_str) {
	if ((old_name = _zip_string_get(old_str, NULL, 0, &za->error)) == NULL) {
	    _zip_string_free(str);
	    return -1;
	}
    }
    else {
	old_name = NULL;
    }

    if (_zip_hash_add(za->names, new_name, idx, 0, &za->error) == false) {
	_zip_string_free(str);
	return -1;
    }
    if (old_name) {
	_zip_hash_delete(za->names, old_name, NULL);
    }

    if (same_as_orig) {
	if (e->changes) {
	    if (e->changes->changed & ZIP_DIRENT_FILENAME) {
		_zip_string_free(e->changes->filename);
		e->changes->changed &= ~ZIP_DIRENT_FILENAME;
		if (e->changes->changed == 0) {
		    _zip_dirent_free(e->changes);
		    e->changes = NULL;
		}
		else {
		    /* TODO: what if not cloned? can that happen? */
		    e->changes->filename = e->orig->filename;
		}
	    }
	}
	_zip_string_free(str);
    }
    else {
	if (e->changes->changed & ZIP_DIRENT_FILENAME) {
	    _zip_string_free(e->changes->filename);
	}
	e->changes->changed |= ZIP_DIRENT_FILENAME;
	e->changes->filename = str;
    }

    return 0;
}