blob: e4e0d015a84571c5c3972e3e45773b480eb54574 [file] [log] [blame]
#include <stdlib.h>
#include "zip.h"
#include "xmalloc.h"
static int zip_unchange_data(struct zf *zf, int idx);
static int zip_set_name(struct zf *zf, int idx, char *name);
int
zip_rename(struct zf *zf, int idx, char *name)
{
if (idx >= zf->nentry || idx < 0)
return -1;
if (zf->entry[idx].state == Z_UNCHANGED)
zf->entry[idx].state = Z_RENAMED;
zf->changes = 1;
zip_set_name(zf, idx, name);
return idx;
}
int
zip_add_file(struct zf *zf, char *name, FILE *file,
int start, int len)
{
zip_new_entry(zf);
zf->changes = 1;
zip_set_name(zf, zf->nentry-1, name ? name : "-");
zf->entry[zf->nentry-1].ch_data_fp = file;
zf->entry[zf->nentry-1].ch_data_offset = start;
zf->entry[zf->nentry-1].ch_data_len = len;
return zf->nentry-1;
}
int
zip_add_data(struct zf *zf, char *name, char *buf,
int start, int len)
{
zip_new_entry(zf);
zf->changes = 1;
zip_set_name(zf, zf->nentry-1, name ? name : "-");
zf->entry[zf->nentry-1].ch_data_buf = buf;
zf->entry[zf->nentry-1].ch_data_offset = start;
zf->entry[zf->nentry-1].ch_data_len = len;
return zf->nentry-1;
}
int
zip_add_zip(struct zf *zf, char *name, struct zf *srczf, int srcidx,
int start, int len)
{
if (srcidx >= srczf->nentry || srcidx < 0)
return -1;
zip_new_entry(zf);
zf->changes = 1;
zip_set_name(zf, zf->nentry-1, name ? name : srczf->entry[srcidx].fn);
zf->entry[zf->nentry-1].ch_data_zf = srczf;
zf->entry[zf->nentry-1].ch_data_zf_fileno = srcidx;
zf->entry[zf->nentry-1].ch_data_offset = start;
zf->entry[zf->nentry-1].ch_data_len = len;
return zf->nentry-1;
}
int
zip_replace_file(struct zf *zf, int idx, char *name, FILE *file,
int start, int len)
{
if (idx >= zf->nentry || idx < 0)
return -1;
zip_unchange_data(zf, idx);
zf->changes = 1;
zf->entry[idx].state = Z_REPLACED;
zip_set_name(zf, idx, name);
zf->entry[idx].ch_data_fp = file;
zf->entry[idx].ch_data_offset = start;
zf->entry[idx].ch_data_len = len;
return idx;
}
int
zip_replace_data(struct zf *zf, int idx, char *name, char *buf,
int start, int len)
{
if (idx >= zf->nentry || idx < 0)
return -1;
zip_unchange_data(zf, idx);
zf->changes = 1;
zf->entry[idx].state = Z_REPLACED;
zip_set_name(zf, idx, name);
zf->entry[idx].ch_data_buf = buf;
zf->entry[idx].ch_data_offset = start;
zf->entry[idx].ch_data_len = len;
return idx;
}
int
zip_replace_zip(struct zf *zf, int idx, char *name, struct zf *srczf,
int srcidx, int start, int len)
{
if (idx >= zf->nentry || idx < 0)
return -1;
if (srcidx >= srczf->nentry || srcidx < 0)
return -1;
zip_unchange_data(zf, idx);
zf->changes = 1;
zf->entry[idx].state = Z_REPLACED;
zip_set_name(zf, idx, name);
zf->entry[idx].ch_data_zf = srczf;
zf->entry[idx].ch_data_zf_fileno = srcidx;
zf->entry[idx].ch_data_offset = start;
zf->entry[idx].ch_data_len = len;
return idx;
}
int
zip_delete(struct zf *zf, int idx)
{
if (idx >= zf->nentry || idx < 0)
return -1;
zip_unchange(zf, idx);
zf->changes = 1;
zf->entry[idx].state = Z_DELETED;
return idx;
}
int
zip_unchange(struct zf *zf, int idx)
{
if (idx >= zf->nentry || idx < 0)
return -1;
if (zf->entry[idx].fn_old) {
free(zf->entry[idx].fn);
zf->entry[idx].fn = zf->entry[idx].fn_old;
zf->entry[idx].fn_old = NULL;
zf->entry[idx].fnlen = strlen(zf->entry[idx].fn);
}
return zip_unchange_data(zf, idx);
}
static int
zip_unchange_data(struct zf *zf, int idx)
{
if (idx >= zf->nentry || idx < 0)
return -1;
if (zf->entry[idx].ch_data_fp) {
fclose(zf->entry[idx].ch_data_fp);
zf->entry[idx].ch_data_fp = NULL;
}
if (zf->entry[idx].ch_data_buf) {
free(zf->entry[idx].ch_data_buf);
zf->entry[idx].ch_data_buf = NULL;
}
zf->entry[idx].ch_data_zf = NULL;
zf->entry[idx].ch_data_zf_fileno = 0;
zf->entry[idx].ch_data_offset = 0;
zf->entry[idx].ch_data_len = 0;
zf->entry[idx].state = zf->entry[idx].fn_old ? Z_RENAMED : Z_UNCHANGED;
return idx;
}
static int
zip_set_name(struct zf *zf, int idx, char *name)
{
if (idx >= zf->nentry || idx < 0)
return -1;
if (name != NULL) {
if (zf->entry[idx].fn_old == NULL)
zf->entry[idx].fn_old = zf->entry[idx].fn;
else
free(zf->entry[idx].fn);
zf->entry[idx].fn = xstrdup(name);
zf->entry[idx].fnlen = strlen(name);
}
return idx;
}
void
zip_entry_init(struct zf *zf, int idx)
{
zf->entry[idx].fn = zf->entry[idx].ef = zf->entry[idx].fcom =
zf->entry[idx].fn_old = NULL;
zf->entry[idx].state = Z_UNCHANGED;
zf->entry[idx].ch_data_zf = NULL;
zf->entry[idx].ch_data_buf = NULL;
zf->entry[idx].ch_data_fp = NULL;
zf->entry[idx].ch_data_offset = zf->entry[idx].ch_data_len = 0;
zf->entry[idx].ch_data_zf_fileno = 0;
}
void
zip_new_entry(struct zf *zf)
{
if (zf->nentry >= zf->nentry_alloc-1) {
zf->nentry_alloc += 16;
zf->entry = (struct zf_entry *)xrealloc(zf->entry,
sizeof(struct zf_entry)
* zf->nentry_alloc);
}
zip_entry_init(zf, zf->nentry);
zf->entry[zf->nentry].fn_old = NULL;
zf->entry[zf->nentry].state = Z_ADDED;
zf->nentry++;
}