int main(int argc, char *argv[]) { const char *archive; struct zip *za; char buf[100]; int err; int i; prg = argv[0]; if (argc != 2) { fprintf(stderr, "usage: %s archive\n", prg); return 1; } archive = argv[1]; if ((za=zip_open(archive, 0, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "%s: can't open zip archive `%s': %s\n", prg, archive, buf); return 1; } if (zip_set_archive_comment(za, new_archive_comment, (zip_uint16_t)strlen(new_archive_comment)) < 0) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "%s: zip_set_archive_comment failed: %s\n", prg, buf); } for (i=0; i<zip_get_num_entries(za, 0); i++) { snprintf(buf, sizeof(buf), "File comment no %d", i); if (zip_file_set_comment(za, i, buf, (zip_uint16_t)strlen(buf), 0) < 0) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "%s: zip_set_file_comment on file %d failed: %s\n", prg, i, buf); } } if (zip_unchange_all(za) == -1) { fprintf(stderr, "%s: can't revert changes to archive `%s'\n", prg, archive); return 1; } if (zip_close(za) == -1) { fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); return 1; } return 0; }
static int S_archive_set_archive_comment(lua_State* L) { struct zip** ar = check_archive(L, 1); size_t comment_len = 0; const char* comment = lua_isnil(L, 2) ? NULL : luaL_checklstring(L, 2, &comment_len); if ( ! *ar ) return 0; if ( 0 != zip_set_archive_comment(*ar, comment, comment_len) ) { lua_pushstring(L, zip_strerror(*ar)); lua_error(L); } return 0; }
static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment) { struct zipruby_archive *p_archive; const char *s_comment = NULL; int len = 0; if (!NIL_P(comment)) { Check_Type(comment, T_STRING); s_comment = RSTRING_PTR(comment); len = RSTRING_LEN(comment); } Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (zip_set_archive_comment(p_archive->archive, s_comment, len) == -1) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Comment archived failed: %s", zip_strerror(p_archive->archive)); } return Qnil; }
int main(int argc, char *argv[]) { const char *archive; struct zip *za; char buf[100]; int err; prg = argv[0]; if (argc != 2) { fprintf(stderr, "usage: %s archive\n", prg); return 1; } archive = argv[1]; if ((za=zip_open(archive, 0, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "%s: can't open zip archive `%s': %s\n", prg, archive, buf); return 1; } if (zip_set_archive_comment(za, NULL, 0) < 0) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "%s: zip_set_archive_comment failed: %s\n", prg, buf); } if (zip_close(za) == -1) { fprintf(stderr, "%s: can't close zip archive `%s': %s\n", prg, archive, zip_strerror(za)); return 1; } return 0; }
ZIP_EXTERN int zip_close(struct zip *za) { zip_uint64_t i, j, survivors; int error; char *temp; FILE *out; #ifndef _WIN32 mode_t mask; #endif struct zip_filelist *filelist; int reopen_on_error; int new_torrentzip; int changed; reopen_on_error = 0; if (za == NULL) return -1; changed = _zip_changed(za, &survivors); /* don't create zip files with no entries */ if (survivors == 0) { if (za->zn && ((za->open_flags & ZIP_TRUNCATE) || (changed && za->zp))) { if (remove(za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_REMOVE, errno); return -1; } } zip_discard(za); return 0; } if (!changed) { zip_discard(za); return 0; } if (survivors > za->nentry) { _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } if ((filelist=(struct zip_filelist *)malloc(sizeof(filelist[0])*(size_t)survivors)) == NULL) return -1; /* archive comment is special for torrentzip */ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) { /* TODO: use internal function when zip_set_archive_comment clears TORRENT flag */ if (zip_set_archive_comment(za, TORRENT_SIG "XXXXXXXX", TORRENT_SIG_LEN + TORRENT_CRC_LEN) < 0) { free(filelist); return -1; } } /* TODO: if no longer torrentzip and archive comment not changed by user, delete it */ /* create list of files with index into original archive */ for (i=j=0; i<za->nentry; i++) { if (za->entry[i].deleted) continue; if (j >= survivors) { free(filelist); _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } filelist[j].idx = i; filelist[j].name = zip_get_name(za, i, 0); j++; } if (j < survivors) { free(filelist); _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); return -1; } if ((temp=_zip_create_temp_output(za, &out)) == NULL) { free(filelist); return -1; } if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) qsort(filelist, (size_t)survivors, sizeof(filelist[0]), _zip_torrentzip_cmp); new_torrentzip = (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 1 && zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0); error = 0; for (j=0; j<survivors; j++) { int new_data; struct zip_entry *entry; struct zip_dirent *de; i = filelist[j].idx; entry = za->entry+i; new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || new_torrentzip || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD)); /* create new local directory entry */ if (entry->changes == NULL) { if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); error = 1; break; } } de = entry->changes; if (_zip_read_local_ef(za, i) < 0) { error = 1; break; } if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) _zip_dirent_torrent_normalize(entry->changes); de->offset = (zip_uint64_t)ftello(out); /* TODO: check for errors */ if (new_data) { struct zip_source *zs; zs = NULL; if (!ZIP_ENTRY_DATA_CHANGED(entry)) { if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { error = 1; break; } } /* add_data writes dirent */ if (add_data(za, zs ? zs : entry->source, de, out) < 0) { error = 1; if (zs) zip_source_free(zs); break; } if (zs) zip_source_free(zs); } else { zip_uint64_t offset; /* when copying data, all sizes are known -> no data descriptor needed */ de->bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; if (_zip_dirent_write(de, out, ZIP_FL_LOCAL, &za->error) < 0) { error = 1; break; } if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) { error = 1; break; } if ((fseeko(za->zp, (off_t)offset, SEEK_SET) < 0)) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); error = 1; break; } if (copy_data(za->zp, de->comp_size, out, &za->error) < 0) { error = 1; break; } } } if (!error) { if (write_cdir(za, filelist, survivors, out) < 0) error = 1; } free(filelist); if (error) { fclose(out); (void)remove(temp); free(temp); return -1; } if (fclose(out) != 0) { _zip_error_set(&za->error, ZIP_ER_CLOSE, errno); (void)remove(temp); free(temp); return -1; } if (za->zp) { fclose(za->zp); za->zp = NULL; reopen_on_error = 1; } if (_zip_rename(temp, za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_RENAME, errno); (void)remove(temp); free(temp); if (reopen_on_error) { /* ignore errors, since we're already in an error case */ za->zp = fopen(za->zn, "rb"); } return -1; } #ifndef _WIN32 mask = umask(0); umask(mask); chmod(za->zn, 0666&~mask); #endif zip_discard(za); free(temp); return 0; }