summaryrefslogtreecommitdiff
path: root/ext/zip/lib/zip_source_filep.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/zip/lib/zip_source_filep.c')
-rw-r--r--ext/zip/lib/zip_source_filep.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/ext/zip/lib/zip_source_filep.c b/ext/zip/lib/zip_source_filep.c
index 8a3304265..2a06a9f02 100644
--- a/ext/zip/lib/zip_source_filep.c
+++ b/ext/zip/lib/zip_source_filep.c
@@ -1,11 +1,9 @@
/*
- $NiH: zip_source_filep.c,v 1.6 2005/06/09 19:57:10 dillo Exp $
-
zip_source_filep.c -- create data source from FILE *
- Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <nih@giga.or.at>
+ The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -41,10 +39,10 @@
#include <stdlib.h>
#include <string.h>
-#include "zip.h"
#include "zipint.h"
struct read_file {
+ char *fname; /* name of file to copy from */
FILE *f; /* file to copy from */
off_t off; /* start offset of */
off_t len; /* lengt of data to copy */
@@ -57,12 +55,9 @@ static ssize_t read_file(void *state, void *data, size_t len,
-PHPZIPAPI struct zip_source *
+ZIP_EXTERN(struct zip_source *)
zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
{
- struct read_file *f;
- struct zip_source *zs;
-
if (za == NULL)
return NULL;
@@ -71,11 +66,36 @@ zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
return NULL;
}
+ return _zip_source_file_or_p(za, NULL, file, start, len);
+}
+
+
+
+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);
@@ -102,6 +122,14 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
switch (cmd) {
case ZIP_SOURCE_OPEN:
+ if (z->fname) {
+ if ((z->f=fopen(z->fname, "rb")) == NULL) {
+ z->e[0] = ZIP_ER_OPEN;
+ z->e[1] = errno;
+ return -1;
+ }
+ }
+
if (fseeko(z->f, z->off, SEEK_SET) < 0) {
z->e[0] = ZIP_ER_SEEK;
z->e[1] = errno;
@@ -128,17 +156,27 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
return i;
case ZIP_SOURCE_CLOSE:
+ if (z->fname) {
+ fclose(z->f);
+ z->f = NULL;
+ }
return 0;
case ZIP_SOURCE_STAT:
{
struct zip_stat *st;
struct stat fst;
+ int err;
if (len < sizeof(*st))
return -1;
- if (fstat(fileno(z->f), &fst) != 0) {
+ if (z->f)
+ err = fstat(fileno(z->f), &fst);
+ else
+ err = stat(z->fname, &fst);
+
+ if (err != 0) {
z->e[0] = ZIP_ER_READ; /* best match */
z->e[1] = errno;
return -1;
@@ -164,6 +202,8 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
return sizeof(int)*2;
case ZIP_SOURCE_FREE:
+ free(z->fname);
+ if (z->f)
fclose(z->f);
free(z);
return 0;