static VALUE zipruby_archive_frename(VALUE self, VALUE index, VALUE name) { struct zipruby_archive *p_archive; Check_Type(name, T_STRING); Data_Get_Struct(self, struct zipruby_archive, p_archive); Check_Archive(p_archive); if (zip_rename(p_archive->archive, NUM2INT(index), RSTRING_PTR(name)) == -1) { zip_unchange_all(p_archive->archive); zip_unchange_archive(p_archive->archive); rb_raise(Error, "Rename file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive)); } return Qnil; }
static int zip_append(const struct sr_output *o, unsigned char *buf, int unitsize, int length) { struct out_context *outc; struct zip *archive; struct zip_source *logicsrc; zip_int64_t num_files; struct zip_file *zf; struct zip_stat zs; struct zip_source *metasrc; GKeyFile *kf; GError *error; gsize len; int chunk_num, next_chunk_num, tmpfile, ret, i; const char *entry_name; char *metafile, tmpname[32], chunkname[16]; outc = o->priv; if (!(archive = zip_open(outc->filename, 0, &ret))) return SR_ERR; if (zip_stat(archive, "metadata", 0, &zs) == -1) return SR_ERR; metafile = g_malloc(zs.size); zf = zip_fopen_index(archive, zs.index, 0); zip_fread(zf, metafile, zs.size); zip_fclose(zf); /* * If the file was only initialized but doesn't yet have any * data it in, it won't have a unitsize field in metadata yet. */ error = NULL; kf = g_key_file_new(); if (!g_key_file_load_from_data(kf, metafile, zs.size, 0, &error)) { sr_err("Failed to parse metadata: %s.", error->message); return SR_ERR; } g_free(metafile); tmpname[0] = '\0'; if (!g_key_file_has_key(kf, "device 1", "unitsize", &error)) { if (error && error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { sr_err("Failed to check unitsize key: %s", error ? error->message : "?"); return SR_ERR; } /* Add unitsize field. */ g_key_file_set_integer(kf, "device 1", "unitsize", unitsize); metafile = g_key_file_to_data(kf, &len, &error); strcpy(tmpname, "sigrok-meta-XXXXXX"); if ((tmpfile = g_mkstemp(tmpname)) == -1) return SR_ERR; if (write(tmpfile, metafile, len) < 0) { sr_dbg("Failed to create new metadata: %s", strerror(errno)); g_free(metafile); unlink(tmpname); return SR_ERR; } close(tmpfile); if (!(metasrc = zip_source_file(archive, tmpname, 0, -1))) { sr_err("Failed to create zip source for metadata."); g_free(metafile); unlink(tmpname); return SR_ERR; } if (zip_replace(archive, zs.index, metasrc) == -1) { sr_err("Failed to replace metadata file."); g_free(metafile); unlink(tmpname); return SR_ERR; } g_free(metafile); } g_key_file_free(kf); next_chunk_num = 1; num_files = zip_get_num_entries(archive, 0); for (i = 0; i < num_files; i++) { entry_name = zip_get_name(archive, i, 0); if (strncmp(entry_name, "logic-1", 7)) continue; if (strlen(entry_name) == 7) { /* This file has no extra chunks, just a single "logic-1". * Rename it to "logic-1-1" * and continue with chunk 2. */ if (zip_rename(archive, i, "logic-1-1") == -1) { sr_err("Failed to rename 'logic-1' to 'logic-1-1'."); unlink(tmpname); return SR_ERR; } next_chunk_num = 2; break; } else if (strlen(entry_name) > 8 && entry_name[7] == '-') { chunk_num = strtoull(entry_name + 8, NULL, 10); if (chunk_num >= next_chunk_num) next_chunk_num = chunk_num + 1; } } snprintf(chunkname, 15, "logic-1-%d", next_chunk_num); if (!(logicsrc = zip_source_buffer(archive, buf, length, FALSE))) { unlink(tmpname); return SR_ERR; } if (zip_add(archive, chunkname, logicsrc) == -1) { unlink(tmpname); return SR_ERR; } if ((ret = zip_close(archive)) == -1) { sr_info("error saving session file: %s", zip_strerror(archive)); unlink(tmpname); return SR_ERR; } unlink(tmpname); return SR_OK; }
int main(int argc, char *argv[]) { const char *archive; struct zip *za, *z_in; struct zip_source *zs; char buf[100]; int c, arg, err, flags, idx; flags = 0; prg = argv[0]; if (argc < 2) { fprintf(stderr, usage, prg); return 1; } while ((c=getopt(argc, argv, "cent")) != -1) { switch (c) { case 'c': flags |= ZIP_CHECKCONS; break; case 'e': flags |= ZIP_EXCL; break; case 'n': flags |= ZIP_CREATE; break; case 't': flags |= ZIP_TRUNCATE; break; default: fprintf(stderr, usage, argv[0]); return 1; } } arg = optind; archive = argv[arg++]; if (flags == 0) flags = ZIP_CREATE; if ((za=zip_open(archive, flags, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "can't open zip archive `%s': %s\n", archive, buf); return 1; } err = 0; while (arg < argc) { if (strcmp(argv[arg], "add") == 0 && arg+2 < argc) { /* add */ if ((zs=zip_source_buffer(za, argv[arg+2], strlen(argv[arg+2]), 0)) == NULL) { fprintf(stderr, "can't create zip_source from buffer: %s\n", zip_strerror(za)); err = 1; break; } if (zip_add(za, argv[arg+1], zs) == -1) { zip_source_free(zs); fprintf(stderr, "can't add file `%s': %s\n", argv[arg+1], zip_strerror(za)); err = 1; break; } arg += 3; } else if (strcmp(argv[arg], "add_dir") == 0 && arg+1 < argc) { /* add directory */ if (zip_add_dir(za, argv[arg+1]) < 0) { fprintf(stderr, "can't add directory `%s': %s\n", argv[arg+1], zip_strerror(za)); err = 1; break; } arg += 2; } else if (strcmp(argv[arg], "add_file") == 0 && arg+4 < argc) { /* add */ if ((zs=zip_source_file(za, argv[arg+2], atoi(argv[arg+3]), atoi(argv[arg+4]))) == NULL) { fprintf(stderr, "can't create zip_source from file: %s\n", zip_strerror(za)); err = 1; break; } if (zip_add(za, argv[arg+1], zs) == -1) { zip_source_free(zs); fprintf(stderr, "can't add file `%s': %s\n", argv[arg+1], zip_strerror(za)); err = 1; break; } arg += 5; } else if (strcmp(argv[arg], "add_from_zip") == 0 && arg+5 < argc) { /* add from another zip file */ idx = atoi(argv[arg+3]); if ((z_in=zip_open(argv[arg+2], ZIP_CHECKCONS, &err)) == NULL) { zip_error_to_str(buf, sizeof(buf), err, errno); fprintf(stderr, "can't open source zip archive `%s': %s\n", argv[arg+2], buf); err = 1; break; } if ((zs=zip_source_zip(za, z_in, idx, 0, atoi(argv[arg+4]), atoi(argv[arg+5]))) == NULL) { fprintf(stderr, "error creating file source from `%s' index '%d': %s\n", argv[arg+2], idx, zip_strerror(za)); zip_close(z_in); err = 1; break; } if (zip_add(za, argv[arg+1], zs) == -1) { fprintf(stderr, "can't add file `%s': %s\n", argv[arg+1], zip_strerror(za)); zip_source_free(zs); zip_close(z_in); err = 1; break; } arg += 6; } else if (strcmp(argv[arg], "count_extra") == 0 && arg+2 < argc) { zip_int16_t count; zip_flags_t ceflags = 0; idx = atoi(argv[arg+1]); ceflags = get_flags(argv[arg+2]); if ((count=zip_file_extra_fields_count(za, idx, ceflags)) < 0) { fprintf(stderr, "can't get extra field count for file at index `%d': %s\n", idx, zip_strerror(za)); err = 1; break; } else { printf("Extra field count: %d\n", count); } arg += 3; } else if (strcmp(argv[arg], "count_extra_by_id") == 0 && arg+3 < argc) { zip_int16_t count, eid; zip_flags_t ceflags = 0; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); ceflags = get_flags(argv[arg+3]); if ((count=zip_file_extra_fields_count_by_id(za, idx, eid, ceflags)) < 0) { fprintf(stderr, "can't get extra field count for file at index `%d' and for id `%d': %s\n", idx, eid, zip_strerror(za)); err = 1; break; } else { printf("Extra field count: %d\n", count); } arg += 4; } else if (strcmp(argv[arg], "delete") == 0 && arg+1 < argc) { /* delete */ idx = atoi(argv[arg+1]); if (zip_delete(za, idx) < 0) { fprintf(stderr, "can't delete file at index `%d': %s\n", idx, zip_strerror(za)); err = 1; break; } arg += 2; } else if (strcmp(argv[arg], "delete_extra") == 0 && arg+1 < argc) { zip_flags_t geflags; zip_uint16_t eid; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); geflags = get_flags(argv[arg+3]); if ((zip_file_extra_field_delete(za, idx, eid, geflags)) < 0) { fprintf(stderr, "can't delete extra field data for file at index `%d', extra field id `%d': %s\n", idx, eid, zip_strerror(za)); err = 1; break; } arg += 4; } else if (strcmp(argv[arg], "delete_extra_by_id") == 0 && arg+1 < argc) { zip_flags_t geflags; zip_uint16_t eid, eidx; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); eidx = atoi(argv[arg+3]); geflags = get_flags(argv[arg+4]); if ((zip_file_extra_field_delete_by_id(za, idx, eid, eidx, geflags)) < 0) { fprintf(stderr, "can't delete extra field data for file at index `%d', extra field id `%d', extra field idx `%d': %s\n", idx, eid, eidx, zip_strerror(za)); err = 1; break; } arg += 5; } else if (strcmp(argv[arg], "get_archive_comment") == 0) { const char *comment; int len; /* get archive comment */ if ((comment=zip_get_archive_comment(za, &len, 0)) == NULL) printf("No archive comment\n"); else printf("Archive comment: %.*s\n", len, comment); arg += 1; } else if (strcmp(argv[arg], "get_extra") == 0 && arg+3 < argc) { zip_flags_t geflags; zip_uint16_t id, eidx, eflen; const zip_uint8_t *efdata; /* get extra field data */ idx = atoi(argv[arg+1]); eidx = atoi(argv[arg+2]); geflags = get_flags(argv[arg+3]); if ((efdata=zip_file_extra_field_get(za, idx, eidx, &id, &eflen, geflags)) == NULL) { fprintf(stderr, "can't get extra field data for file at index %d, extra field %d, flags %u: %s\n", idx, eidx, geflags, zip_strerror(za)); err = 1; } else { printf("Extra field 0x%04x: len %d", id, eflen); if (eflen > 0) { printf(", data "); hexdump(efdata, eflen); } printf("\n"); } arg += 4; } else if (strcmp(argv[arg], "get_extra_by_id") == 0 && arg+4 < argc) { zip_flags_t geflags; zip_uint16_t eid, eidx, eflen; const zip_uint8_t *efdata; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); eidx = atoi(argv[arg+3]); geflags = get_flags(argv[arg+4]); if ((efdata=zip_file_extra_field_get_by_id(za, idx, eid, eidx, &eflen, geflags)) == NULL) { fprintf(stderr, "can't get extra field data for file at index %d, extra field id %d, ef index %d, flags %u: %s\n", idx, eid, eidx, geflags, zip_strerror(za)); err = 1; } else { printf("Extra field 0x%04x: len %d", eid, eflen); if (eflen > 0) { printf(", data "); hexdump(efdata, eflen); } printf("\n"); } arg += 5; } else if (strcmp(argv[arg], "get_file_comment") == 0 && arg+1 < argc) { const char *comment; int len; /* get file comment */ idx = atoi(argv[arg+1]); if ((comment=zip_get_file_comment(za, idx, &len, 0)) == NULL) { fprintf(stderr, "can't get comment for `%s': %s\n", zip_get_name(za, idx, 0), zip_strerror(za)); err = 1; break; } else if (len == 0) printf("No comment for `%s'\n", zip_get_name(za, idx, 0)); else printf("File comment for `%s': %.*s\n", zip_get_name(za, idx, 0), len, comment); arg += 2; } else if (strcmp(argv[arg], "rename") == 0 && arg+2 < argc) { /* rename */ idx = atoi(argv[arg+1]); if (zip_rename(za, idx, argv[arg+2]) < 0) { fprintf(stderr, "can't rename file at index `%d' to `%s': %s\n", idx, argv[arg+2], zip_strerror(za)); err = 1; break; } arg += 3; } else if (strcmp(argv[arg], "set_extra") == 0 && arg+5 < argc) { zip_flags_t geflags; zip_uint16_t eid, eidx; const zip_uint8_t *efdata; idx = atoi(argv[arg+1]); eid = atoi(argv[arg+2]); eidx = atoi(argv[arg+3]); geflags = get_flags(argv[arg+4]); efdata = (zip_uint8_t *)argv[arg+5]; if ((zip_file_extra_field_set(za, idx, eid, eidx, efdata, (zip_uint16_t)strlen((const char *)efdata), geflags)) < 0) { fprintf(stderr, "can't set extra field data for file at index `%d', extra field id `%d', index `%d': %s\n", idx, eid, eidx, zip_strerror(za)); err = 1; break; } arg += 6; } else if (strcmp(argv[arg], "set_file_comment") == 0 && arg+2 < argc) { /* set file comment */ idx = atoi(argv[arg+1]); if (zip_file_set_comment(za, idx, argv[arg+2], (zip_uint16_t)strlen(argv[arg+2]), 0) < 0) { fprintf(stderr, "can't set file comment at index `%d' to `%s': %s\n", idx, argv[arg+2], zip_strerror(za)); err = 1; break; } arg += 3; } else if (strcmp(argv[arg], "set_file_compression") == 0 && arg+3 < argc) { /* set file compression */ zip_int32_t method; zip_uint32_t flags; idx = atoi(argv[arg+1]); method = get_compression_method(argv[arg+2]); flags = atoi(argv[arg+3]); if (zip_set_file_compression(za, idx, method, flags) < 0) { fprintf(stderr, "can't set file compression method at index `%d' to `%s', flags `%d': %s\n", idx, argv[arg+2], flags, zip_strerror(za)); err = 1; break; } arg += 4; } else { fprintf(stderr, "unrecognized command `%s', or not enough arguments\n", argv[arg]); err = 1; break; } } if (zip_close(za) == -1) { fprintf(stderr, "can't close zip archive `%s': %s\n", archive, zip_strerror(za)); return 1; } return err; }