ZIP_EXTERN int zip_file_extra_field_delete_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags) { struct zip_dirent *de; if ((flags & ZIP_EF_BOTH) == 0) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } 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; } if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) return -1; de = za->entry[idx].changes; de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags); return 0; }
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags) { struct zip_dirent *de; struct zip_extra_field *ef; zip_uint16_t n; if ((flags & ZIP_EF_BOTH) == 0) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) return -1; if (flags & ZIP_FL_LOCAL) if (_zip_read_local_ef(za, idx) < 0) return -1; n = 0; for (ef=de->extra_fields; ef; ef=ef->next) if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) n++; return (zip_int16_t)n; }
const char * _zip_get_name(struct zip *za, zip_uint64_t idx, zip_flags_t flags, struct zip_error *error) { struct zip_dirent *de; const zip_uint8_t *str; if ((de=_zip_get_dirent(za, idx, flags, error)) == NULL) return NULL; if ((str=_zip_string_get(de->filename, NULL, flags, error)) == NULL) return NULL; return (const char *)str; }
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; }
int zip_file_get_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes) { zip_dirent_t *de; if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL) return -1; if (opsys) *opsys = (zip_uint8_t)((de->version_madeby >> 8) & 0xff); if (attributes) *attributes = de->ext_attrib; return 0; }
int zip_file_get_external_attributes(struct zip *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes) { struct zip_dirent *de; zip_uint32_t len; const zip_uint8_t *str; if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL) return -1; if (opsys) *opsys = (de->version_madeby >> 8) & 0xff; if (attributes) *attributes = de->ext_attrib; return 0; }
ZIP_EXTERN const char * zip_file_get_comment(struct zip *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags) { struct zip_dirent *de; zip_uint32_t len; const zip_uint8_t *str; if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL) return NULL; if ((str=_zip_string_get(de->comment, &len, flags, &za->error)) == NULL) return NULL; if (lenp) *lenp = len; return (const char *)str; }
ZIP_EXTERN const zip_uint8_t * zip_file_extra_field_get(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags) { static const zip_uint8_t empty[1] = { '\0' }; struct zip_dirent *de; struct zip_extra_field *ef; int i; if ((flags & ZIP_EF_BOTH) == 0) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) return NULL; if (flags & ZIP_FL_LOCAL) if (_zip_read_local_ef(za, idx) < 0) return NULL; i = 0; for (ef=de->extra_fields; ef; ef=ef->next) { if (ef->flags & flags & ZIP_EF_BOTH) { if (i < ef_idx) { i++; continue; } if (idp) *idp = ef->id; if (lenp) *lenp = ef->size; if (ef->size > 0) return ef->data; else return empty; } } _zip_error_set(&za->error, ZIP_ER_NOENT, 0); return NULL; }
ZIP_EXTERN const zip_uint8_t * zip_file_extra_field_get_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags) { struct zip_dirent *de; if ((flags & ZIP_EF_BOTH) == 0) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) return NULL; if (flags & ZIP_FL_LOCAL) if (_zip_read_local_ef(za, idx) < 0) return NULL; return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error); }
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; }
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; }
ZIP_EXTERN int zip_file_extra_field_set(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags) { struct zip_dirent *de; zip_uint16_t ls, cs; struct zip_extra_field *ef, *ef_prev, *ef_new; int i, found, new_len; if ((flags & ZIP_EF_BOTH) == 0) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } 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; } if (ZIP_EF_IS_INTERNAL(ef_id)) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) return -1; de = za->entry[idx].changes; ef = de->extra_fields; ef_prev = NULL; i = 0; found = 0; for (; ef; ef=ef->next) { if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) { if (i == ef_idx) { found = 1; break; } i++; } ef_prev = ef; } if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } if (flags & ZIP_EF_LOCAL) ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL); else ls = 0; if (flags & ZIP_EF_CENTRAL) cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL); else cs = 0; new_len = ls > cs ? ls : cs; if (found) new_len -= ef->size + 4; new_len += len + 4; if (new_len > ZIP_UINT16_MAX) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return -1; } if (found) { if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) { ef_new->next = ef->next; ef->next = NULL; _zip_ef_free(ef); if (ef_prev) ef_prev->next = ef_new; else de->extra_fields = ef_new; } else { ef->flags &= ~(flags & ZIP_EF_BOTH); ef_new->next = ef->next; ef->next = ef_new; } } else if (ef_prev) { ef_new->next = ef_prev->next; ef_prev->next = ef_new; } else de->extra_fields = ef_new; return 0; }