ZIP_EXTERN int zip_file_rename(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { const char *old_name; int old_is_dir, new_is_dir; if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) { _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 ((old_name=zip_get_name(za, idx, 0)) == NULL) return -1; new_is_dir = (name != NULL && name[strlen(name)-1] == '/'); old_is_dir = (old_name[strlen(old_name)-1] == '/'); if (new_is_dir != old_is_dir) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } return _zip_set_name(za, idx, name, flags); }
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; }
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; }
ZIP_EXTERN int zip_rename(struct zip *za, int idx, const char *name) { const char *old_name; int old_is_dir, new_is_dir; if (idx >= za->nentry || idx < 0 || name[0] == '\0') { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } if ((old_name=zip_get_name(za, idx, 0)) == NULL) return -1; new_is_dir = (name[strlen(name)-1] == '/'); old_is_dir = (old_name[strlen(old_name)-1] == '/'); if (new_is_dir != old_is_dir) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } return _zip_set_name(za, idx, name); }