Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
int
_zip_set_name(struct zip *za, int idx, const char *name)
{
    char *s;
    int i;
    
    if (idx < 0 || idx >= za->nentry || name == NULL) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) {
	_zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
	return -1;
    }

    /* no effective name change */
    if (i == idx)
	return 0;
    
    if ((s=strdup(name)) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return -1;
    }
    
    if (za->entry[idx].state == ZIP_ST_UNCHANGED) 
	za->entry[idx].state = ZIP_ST_RENAMED;

    free(za->entry[idx].ch_filename);
    za->entry[idx].ch_filename = s;

    return 0;
}
Ejemplo n.º 3
0
int
_zip_unchange(struct zip *za, int idx, int allow_duplicates)
{
    int i;
    
    if (idx < 0 || idx >= za->nentry) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

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

	free(za->entry[idx].ch_filename);
	za->entry[idx].ch_filename = NULL;
    }

    free(za->entry[idx].ch_comment);
    za->entry[idx].ch_comment = NULL;
    za->entry[idx].ch_comment_len = -1;

    _zip_unchange_data(za->entry+idx);

    return 0;
}
Ejemplo n.º 4
0
zip_int64_t
_zip_file_replace(struct zip *za, zip_uint64_t idx, const char *name, struct zip_source *source, zip_flags_t flags)
{
    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) {
	zip_int64_t i = -1;
	
	if (flags & ZIP_FL_OVERWRITE)
	    i = _zip_name_locate(za, name, flags, NULL);

	if (i == -1) {
	    /* create and use new entry, used by zip_add */
	    if ((i=_zip_add_entry(za)) < 0)
		return -1;
	}
	idx = (zip_uint64_t)i;
    }
    
    if (name && _zip_set_name(za, idx, name, flags) != 0) {
	if (za->nentry != za_nentry_prev) {
	    _zip_entry_finalize(za->entry+idx);
	    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);

    if (za->entry[idx].orig != NULL && (za->entry[idx].changes == NULL || (za->entry[idx].changes->changed & ZIP_DIRENT_COMP_METHOD) == 0)) {
        if (za->entry[idx].changes == NULL) {
            if ((za->entry[idx].changes=_zip_dirent_clone(za->entry[idx].orig)) == NULL) {
                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return -1;
            }
        }

        za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT;
        za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD;
    }
	
    za->entry[idx].source = source;

    return (zip_int64_t)idx;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
ZIP_EXTERN int
zip_name_locate(struct zip *za, const char *fname, int flags)
{
    return _zip_name_locate(za, fname, flags, &za->error);
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
ZIP_EXTERN zip_int64_t
zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags) {
    return _zip_name_locate(za, fname, flags, &za->error);
}