Esempio n. 1
0
/**
 * Save timestamp into extra fields
 * @return 0 on success
 */
int FileNode::updateExtraFields () const {
    static zip_flags_t locations[] = {ZIP_FL_CENTRAL, ZIP_FL_LOCAL};

    assert (id >= 0);
    assert (zip != NULL);
    for (unsigned int loc = 0; loc < sizeof(locations); ++loc) {
        // remove old extra fields
        zip_int16_t count = zip_file_extra_fields_count (zip, id,
                locations[loc]);
        const zip_uint8_t *field;
        for (zip_int16_t i = count; i >= 0; --i) {
            zip_uint16_t type;
            field = zip_file_extra_field_get (zip, id, i, &type,
                    NULL, locations[loc]);
            // FZ_EF_PKWARE_UNIX not removed because can contain extra data
            // that currently not handled by fuse-zip
            if (field != NULL && (type == FZ_EF_TIMESTAMP ||
                        type == FZ_EF_INFOZIP_UNIX1 ||
                        type == FZ_EF_INFOZIP_UNIX2 ||
                        type == FZ_EF_INFOZIP_UNIXN)) {
                zip_file_extra_field_delete (zip, id, i,
                        locations[loc]);
            }
        }
        // add new extra fields
        zip_uint16_t len;
        int res;
        // add timestamps
        field = ExtraField::createExtTimeStamp (locations[loc], m_mtime,
                m_atime, has_cretime, cretime, len);
        res = zip_file_extra_field_set (zip, id, FZ_EF_TIMESTAMP,
                ZIP_EXTRA_FIELD_NEW, field, len, locations[loc]);
        if (res != 0) {
            return res;
        }
        // add UNIX owner info
        field = ExtraField::createInfoZipNewUnixField (m_uid, m_gid, len);
        res = zip_file_extra_field_set (zip, id, FZ_EF_INFOZIP_UNIXN,
                ZIP_EXTRA_FIELD_NEW, field, len, locations[loc]);
        if (res != 0) {
            return res;
        }
    }
    return 0;
}
Esempio n. 2
0
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;
}