Пример #1
0
struct zip_extra_field *
_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, struct zip_error *error)
{
    struct zip_extra_field *ef, *ef2, *ef_head;
    const zip_uint8_t *p;
    zip_uint16_t fid, flen;

    ef_head = NULL;
    for (p=data; p<data+len; p+=flen) {
	if (p+4 > data+len) {
	    _zip_error_set(error, ZIP_ER_INCONS, 0);
	    _zip_ef_free(ef_head);
	    return NULL;
	}

	fid = _zip_read2(&p);
	flen = _zip_read2(&p);

	if (p+flen > data+len) {
	    _zip_error_set(error, ZIP_ER_INCONS, 0);
	    _zip_ef_free(ef_head);
	    return NULL;
	}

	if ((ef2=_zip_ef_new(fid, flen, p, flags)) == NULL) {
	    _zip_error_set(error, ZIP_ER_MEMORY, 0);
	    _zip_ef_free(ef_head);
	    return NULL;
	}

	if (ef_head) {
	    ef->next = ef2;
	    ef = ef2;
	}
	else
	    ef_head = ef = ef2;
    }

    return ef_head;
}
Пример #2
0
static int
write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out)
{
    off_t offset;
    uLong crc;
    char buf[TORRENT_CRC_LEN+1];
    
    if (_zip_cdir_write(cd, out, &za->error) < 0)
	return -1;
    
    if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0)
	return 0;


    /* fix up torrentzip comment */

    offset = ftello(out);

    if (_zip_filerange_crc(out, cd->offset, cd->size, &crc, &za->error) < 0)
	return -1;

#ifndef _WIN32
    snprintf(buf, sizeof(buf), "%08lX", (long)crc);
#else
    _snprintf(buf, sizeof(buf), "%08lX", (long)crc);
#endif

    if (fseeko(out, offset-TORRENT_CRC_LEN, SEEK_SET) < 0) {
	_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
	return -1;
    }

    if (fwrite(buf, TORRENT_CRC_LEN, 1, out) != 1) {
	_zip_error_set(&za->error, ZIP_ER_WRITE, errno);
	return -1;
    }

    return 0;
}
Пример #3
0
ZIP_EXTERN struct zip_source *
zip_source_file(struct zip *za, const char *fname, off_t start, off_t len)
{
    if (za == NULL)
	return NULL;

    if (fname == NULL || start < 0 || len < -1) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    return _zip_source_file_or_p(za, fname, NULL, start, len);
}
Пример #4
0
ZIP_EXTERN int
zip_delete(struct zip *za, zip_uint64_t idx)
{
    if (idx >= za->nentry) {
	_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;
    }

    /* allow duplicate file names, because the file will
     * be removed directly afterwards */
    if (_zip_unchange(za, idx, 1) != 0)
	return -1;

    za->entry[idx].deleted = 1;

    return 0;
}
Пример #5
0
int
_zip_name_locate(struct zip *za, const char *fname, int flags,
		 struct zip_error *error)
{
    int (*cmp)(const char *, const char *);
    const char *fn, *p;
    int i, n;

    if (fname == NULL) {
	_zip_error_set(error, ZIP_ER_INVAL, 0);
	return -1;
    }
    
    cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;

    n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry;
    for (i=0; i<n; i++) {
	if (flags & ZIP_FL_UNCHANGED)
	    fn = za->cdir->entry[i].filename;
	else
	    fn = _zip_get_name(za, i, flags, error);

	/* newly added (partially filled) entry */
	if (fn == NULL)
	    continue;
	
	if (flags & ZIP_FL_NODIR) {
	    p = strrchr(fn, '/');
	    if (p)
		fn = p+1;
	}

	if (cmp(fname, fn) == 0)
	    return i;
    }

    _zip_error_set(error, ZIP_ER_NOENT, 0);
    return -1;
}
Пример #6
0
zip_int64_t
_zip_name_locate(struct zip *za, const char *fname, zip_flags_t flags, struct zip_error *error)
{
    int (*cmp)(const char *, const char *);
    const char *fn, *p;
    zip_uint64_t i;

    if (za == NULL)
	return -1;

    if (fname == NULL) {
	_zip_error_set(error, ZIP_ER_INVAL, 0);
	return -1;
    }

    cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;

    for (i=0; i<za->nentry; i++) {
	fn = _zip_get_name(za, i, flags, error);

	/* newly added (partially filled) entry or error */
	if (fn == NULL)
	    continue;
	
	if (flags & ZIP_FL_NODIR) {
	    p = strrchr(fn, '/');
	    if (p)
		fn = p+1;
	}

	if (cmp(fname, fn) == 0) {
	    _zip_error_clear(error);
	    return (zip_int64_t)i;
	}
    }

    _zip_error_set(error, ZIP_ER_NOENT, 0);
    return -1;
}
ZIP_EXTERN int
zip_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source)
{
    if (idx >= za->nentry || source == NULL) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if (_zip_replace(za, idx, NULL, source) == -1)
	return -1;

    return 0;
}
Пример #8
0
ZIP_EXTERN struct zip_source *
zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
{
    if (za == NULL)
	return NULL;

    if (file == NULL || start < 0 || len < -1) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    return _zip_source_file_or_p(za, NULL, file, start, len);
}
Пример #9
0
static struct zip_file *
_zip_file_new(struct zip *za)
{
    struct zip_file *zf, **file;
    int n;

    if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }
    
    if (za->nfile >= za->nfile_alloc-1) {
	n = za->nfile_alloc + 10;
	file = (struct zip_file **)realloc(za->file,
					   n*sizeof(struct zip_file *));
	if (file == NULL) {
	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    free(zf);
	    return NULL;
	}
	za->nfile_alloc = n;
	za->file = file;
    }

    za->file[za->nfile++] = zf;

    zf->za = za;
    _zip_error_init(&zf->error);
    zf->flags = 0;
    zf->crc = crc32(0L, Z_NULL, 0);
    zf->crc_orig = 0;
    zf->method = -1;
    zf->bytes_left = zf->cbytes_left = 0;
    zf->fpos = 0;
    zf->buffer = NULL;
    zf->zstr = NULL;

    return zf;
}
Пример #10
0
static char *
_zip_create_temp_output(struct zip *za, FILE **outp)
{
    char *temp;
    int tfd;
    FILE *tfp;
    
    if ((temp=(char *)malloc(strlen(za->zn)+8)) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    sprintf(temp, "%s.XXXXXX", za->zn);

    if ((tfd=mkstemp(temp)) == -1) {
	_zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno);
	free(temp);
	return NULL;
    }
    
    if ((tfp=fdopen(tfd, "r+b")) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno);
	close(tfd);
	remove(temp);
	free(temp);
	return NULL;
    }

#ifdef _WIN32
    /*
      According to Pierre Joye, Windows in some environments per
      default creates text files, so force binary mode.
    */
    _setmode(_fileno(tfp), _O_BINARY );
#endif

    *outp = tfp;
    return temp;
}
Пример #11
0
ZIP_EXTERN int
zip_add_dir(struct zip *za, const char *name)
{
    int len, ret;
    char *s;
    struct zip_source *source;

    if (name == NULL) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    s = NULL;
    len = (int)strlen(name);

    if (name[len-1] != '/') {
	if ((s=(char *)malloc(len+2)) == NULL) {
	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    return -1;
	}
	strcpy(s, name);
	s[len] = '/';
	s[len+1] = '\0';
    }

    if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) {
	free(s);
	return -1;
    }
	
    ret = _zip_replace(za, -1, s ? s : name, source);

    free(s);
    if (ret < 0)
	zip_source_free(source);

    return ret;
}
Пример #12
0
ZIP_EXTERN struct zip_source *
zip_source_pkware(struct zip *za, struct zip_source *src,
		  zip_uint16_t em, int flags, const char *password)
{
    struct trad_pkware *ctx;
    struct zip_source *s2;

    if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }
    if (flags & ZIP_CODEC_ENCODE) {
	_zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
	return NULL;
    }

    if (crc == NULL)
	crc = get_crc_table();

    if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    ctx->e[0] = ctx->e[1] = 0;

    ctx->key[0] = KEY0;
    ctx->key[1] = KEY1;
    ctx->key[2] = KEY2;
    decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);

    if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
	pkware_free(ctx);
	return NULL;
    }

    return s2;
}
Пример #13
0
static int
write_cdir(struct zip *za, const struct zip_filelist *filelist, zip_uint64_t survivors, FILE *out)
{
    off_t cd_start, end;
    zip_int64_t size;
    uLong crc;
    char buf[TORRENT_CRC_LEN+1];
    
    cd_start = ftello(out);

    if ((size=_zip_cdir_write(za, filelist, survivors, out)) < 0)
	return -1;
    
    end = ftello(out);

    if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0)
	return 0;


    /* fix up torrentzip comment */

    if (_zip_filerange_crc(out, cd_start, size, &crc, &za->error) < 0)
	return -1;

    snprintf(buf, sizeof(buf), "%08lX", (long)crc);

    if (fseeko(out, end-TORRENT_CRC_LEN, SEEK_SET) < 0) {
	_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
	return -1;
    }

    if (fwrite(buf, TORRENT_CRC_LEN, 1, out) != 1) {
	_zip_error_set(&za->error, ZIP_ER_WRITE, errno);
	return -1;
    }

    return 0;
}
Пример #14
0
struct zip_entry *
_zip_entry_new(struct zip *za)
{
    struct zip_entry *ze;
    if (!za) {
	ze = (struct zip_entry *)malloc(sizeof(struct zip_entry));
	if (!ze) {
	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    return NULL;
	}
    }
    else {
	if (za->nentry >= za->nentry_alloc-1) {
	    za->nentry_alloc += 16;
	    za->entry = (struct zip_entry *)realloc(za->entry,
						    sizeof(struct zip_entry)
						    * za->nentry_alloc);
	    if (!za->entry) {
		_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
		return NULL;
	    }
	}
	ze = za->entry+za->nentry;
    }

    ze->state = ZIP_ST_UNCHANGED;

    ze->ch_filename = NULL;
    ze->ch_comment = NULL;
    ze->ch_comment_len = -1;
    ze->source = NULL;

    if (za)
	za->nentry++;

    return ze;
}
Пример #15
0
struct zip_source *
zip_source_deflate(struct zip *za, struct zip_source *src,
		   zip_int32_t cm, int flags)
{
    struct deflate *ctx;
    struct zip_source *s2;

    if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    ctx->e[0] = ctx->e[1] = 0;
    ctx->eof = 0;
    if (flags & ZIP_CODEC_ENCODE) {
	if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
	    ctx->mem_level = TORRENT_MEM_LEVEL;
	else
	    ctx->mem_level = MAX_MEM_LEVEL;
    }

    if ((s2=zip_source_layered(za, src,
			       ((flags & ZIP_CODEC_ENCODE)
				? deflate_compress : deflate_decompress),
			       ctx)) == NULL) {
	deflate_free(ctx);
	return NULL;
    }

    return s2;
}
Пример #16
0
struct zip_source *
_zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
		      off_t start, off_t len)
{
    struct read_file *f;
    struct zip_source *zs;

    if (file == NULL && fname == NULL) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((f=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    f->fname = NULL;
    if (fname) {
	if ((f->fname=strdup(fname)) == NULL) {
	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    free(f);
	    return NULL;
	}
    }
    f->f = file;
    f->off = start;
    f->len = (len ? len : -1);
    
    if ((zs=zip_source_function(za, read_file, f)) == NULL) {
	free(f);
	return NULL;
    }

    return zs;
}
const char *
_zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error)
{
    if (idx < 0 || idx >= za->nentry) {
	_zip_error_set(error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((flags & ZIP_FL_UNCHANGED) == 0) {
	if (za->entry[idx].state == ZIP_ST_DELETED) {
	    _zip_error_set(error, ZIP_ER_DELETED, 0);
	    return NULL;
	}
	if (za->entry[idx].ch_filename)
	    return za->entry[idx].ch_filename;
    }

    if (za->cdir == NULL || idx >= za->cdir->nentry) {
	_zip_error_set(error, ZIP_ER_INVAL, 0);
	return NULL;
    }
    
    return za->cdir->entry[idx].filename;
}
zip_uint64_t
_zip_file_get_offset(const struct zip *za, zip_uint64_t idx, struct zip_error *error)
{
    zip_uint64_t offset;
    zip_int32_t size;

    offset = za->entry[idx].orig->offset;

    if (fseeko(za->zp, (off_t)offset, SEEK_SET) != 0) {
        _zip_error_set(error, ZIP_ER_SEEK, errno);
        return 0;
    }

    /* TODO: cache? */
    if ((size=_zip_dirent_size(za->zp, ZIP_EF_LOCAL, error)) < 0)
        return 0;

    if (offset+(zip_uint32_t)size > ZIP_OFF_MAX) {
        _zip_error_set(error, ZIP_ER_SEEK, EFBIG);
        return 0;
    }

    return offset + (zip_uint32_t)size;
}
Пример #19
0
void *
_zip_memdup(const void *mem, size_t len, struct zip_error *error)
{
    void *ret;

    ret = malloc(len);
    if (!ret) {
	_zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    memcpy(ret, mem, len);

    return ret;
}
Пример #20
0
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);
}
Пример #21
0
ZIP_EXTERN int
zip_delete(struct zip *za, int idx)
{
    if (idx < 0 || idx >= za->nentry) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    /* allow duplicate file names, because the file will
     * be removed directly afterwards */
    if (_zip_unchange(za, idx, 1) != 0)
	return -1;

    za->entry[idx].state = ZIP_ST_DELETED;

    return 0;
}
Пример #22
0
zip_source_function(struct zip *za, zip_source_callback zcb, void *ud)
{
    struct zip_source *zs;

    if (za == NULL)
	return NULL;

    if ((zs=(struct zip_source *)malloc(sizeof(*zs))) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    zs->f = zcb;
    zs->ud = ud;
    
    return zs;
}
Пример #23
0
struct zip_source *
_zip_source_new(struct zip *za)
{
    struct zip_source *src;

    if ((src=(struct zip_source *)malloc(sizeof(*src))) == NULL) {
	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    src->src = NULL;
    src->cb.f = NULL;
    src->ud = NULL;
    src->error_source = ZIP_LES_NONE;
    src->is_open = 0;

    return src;
}
Пример #24
0
ZIP_EXTERN int
zip_fseek(struct zip_file *zf, long pos, int whence)
{
    off_t abspos, flen;
    
    if (!zf)
        return -1;
    
    if (zf->error.zip_err != 0)
        return -1;
    
    if (pos == 0 && whence == ZIP_SEEK_CUR)
        return 0;
    
    flen = zf->za->cdir->entry[zf->file_index].uncomp_size;
    
    switch (whence)
    {
        case ZIP_SEEK_CUR:
            abspos = zf->file_fpos + pos;
            break;
        case ZIP_SEEK_SET:
            abspos = pos;
            break;
        case ZIP_SEEK_END:
            abspos = flen + pos;
            break;
        default:
            /* incorrect/unspecified 'whence' parameter */
            _zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
            return -1;
    }
    
    if (abspos == zf->file_fpos)
        return 0;       /* no change */
    
    if ((zf->flags & ZIP_ZF_DECOMP) == 0) {
        // file data is not compressed, or file was opened to read compressed data directly
        return _zip_fseek_bytes(zf, abspos, flen);
    }
    else {
        return _zip_fseek_comp(zf, abspos, flen);
    }
}
Пример #25
0
ZIP_EXTERN int
zip_archive_set_tempdir(struct zip *za, const char *tempdir)
{
    char *new_tempdir;

    if (tempdir) {
        if ((new_tempdir = strdup(tempdir)) == NULL) {
            _zip_error_set(&za->error, ZIP_ER_MEMORY, errno);
            return -1;
        }
    }
    else
        new_tempdir = NULL;

    free(za->tempdir);
    za->tempdir = new_tempdir;

    return 0;
}
Пример #26
0
int _zip_fseek_by_reading(struct zip_file* zf, size_t toread)
{
    char bytes[1024];
    while (toread > 0) {
        ssize_t numRead = zip_fread(zf, bytes, (toread < 1024 ? toread : 1024));
        if (numRead < 0 )
            return -1;      /* error already set */
        if (numRead == 0) {
            /* avoid infinite loops */
            _zip_error_set(&zf->error, ZIP_ER_INCONS, 0);
            return -1;
        }
        
        toread -= numRead;
    }
    
    /* zf has been updated for us by zip_fread() already */
    return 0;
}
Пример #27
0
ZIP_EXTERN struct zip_source *
zip_source_zip(struct zip *za, struct zip *srcza, zip_uint64_t srcidx,
	       zip_flags_t flags, zip_uint64_t start, zip_int64_t len)
{
    if (len < -1) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return NULL;
    }

    if (len == -1)
	len = 0;

    if (start == 0 && len == 0)
	flags |= ZIP_FL_COMPRESSED;
    else
	flags &= ~ZIP_FL_COMPRESSED;

    return _zip_source_zip_new(za, srcza, srcidx, flags, start, (zip_uint64_t)len, NULL);
}
Пример #28
0
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);
}
Пример #29
0
ZIP_EXTERN const char *
zip_get_file_comment(struct zip *za, int idx, int *lenp, int flags)
{
    if (idx < 0 || idx >= za->nentry) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((flags & ZIP_FL_UNCHANGED)
	|| (za->entry[idx].ch_comment_len == -1)) {
	if (lenp != NULL)
	    *lenp = za->cdir->entry[idx].comment_len;
	return za->cdir->entry[idx].comment;
    }
    
    if (lenp != NULL)
	*lenp = za->entry[idx].ch_comment_len;
    return za->entry[idx].ch_comment;
}
unsigned int
_zip_file_get_offset(struct zip *za, int idx)
{
    struct zip_dirent de;
    unsigned int offset;

    offset = za->cdir->entry[idx].offset;

    if (fseeko(za->zp, offset, SEEK_SET) != 0) {
        _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
        return 0;
    }

    if (_zip_dirent_read(&de, za->zp, NULL, 0, 1, &za->error) != 0)
        return 0;

    offset += LENTRYSIZE + de.filename_len + de.extrafield_len;

    _zip_dirent_finalize(&de);

    return offset;
}