summaryrefslogtreecommitdiffstats
path: root/wgtpkg-zip.c
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2015-12-09 14:35:04 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2015-12-09 14:35:04 +0100
commitbf7b5918fcc07713a29b9ca32f766b65b15a4ec2 (patch)
treea4ad318995f3213cee35a2065fc3c4911e2012dc /wgtpkg-zip.c
parent0270b7281b783cbea5c1f0ebb4440d2be1bd79fa (diff)
refactoring sources
Change-Id: Id6d52eee86b706958972e9b345ec0d4d1e488146 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'wgtpkg-zip.c')
-rw-r--r--wgtpkg-zip.c342
1 files changed, 0 insertions, 342 deletions
diff --git a/wgtpkg-zip.c b/wgtpkg-zip.c
deleted file mode 100644
index 9e51538..0000000
--- a/wgtpkg-zip.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- Copyright 2015 IoT.bzh
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-#define _BSD_SOURCE /* see readdir */
-
-#include <limits.h>
-#include <zip.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <assert.h>
-#include <dirent.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "wgtpkg.h"
-
-
-#if !defined(MODE_OF_FILE_CREATION)
-#define MODE_OF_FILE_CREATION 0640
-#endif
-#if !defined(MODE_OF_DIRECTORY_CREATION)
-#define MODE_OF_DIRECTORY_CREATION 0750
-#endif
-
-static int is_valid_filename(const char *filename)
-{
- int lastsp = 0;
- int index = 0;
- unsigned char c;
-
- c = (unsigned char)filename[index];
- while (c) {
- if ((c < 0x1f)
- || ((lastsp = (c == 0x20)) && index == 0)
- || c == 0x7f || c == 0x3c || c == 0x3e
- || c == 0x3a || c == 0x22
- || c == 0x5c || c == 0x7c || c == 0x3f
- || c == 0x2a || c == 0x5e || c == 0x60
- || c == 0x7b || c == 0x7d || c == 0x21)
- return 0;
- c = (unsigned char)filename[++index];
- }
- return !lastsp;
-}
-
-static int create_directory(char *file, int mode)
-{
- int rc;
- char *last = strrchr(file, '/');
- if (last != NULL)
- *last = 0;
- rc = mkdir(file, mode);
- if (rc) {
- if (errno == EEXIST)
- rc = 0;
- else if (errno == ENOENT) {
- rc = create_directory(file, mode);
- if (!rc)
- rc = mkdir(file, mode);
- }
- }
- if (rc)
- syslog(LOG_ERR, "can't create directory %s", file);
- if (last != NULL)
- *last = '/';
- return rc;
-}
-
-static int create_file(char *file, int fmode, int dmode)
-{
- int fd = creat(file, fmode);
- if (fd < 0 && errno == ENOENT) {
- if (!create_directory(file, dmode))
- fd = creat(file, fmode);
- }
- if (fd < 0)
- syslog(LOG_ERR, "can't create file %s", file);
- return fd;
-}
-
-/* read (extract) 'zipfile' in current directory */
-int zread(const char *zipfile, unsigned long long maxsize)
-{
- struct filedesc *fdesc;
- int err, fd, len;
- struct zip *zip;
- zip_int64_t z64;
- unsigned int count, index;
- struct zip_file *zfile;
- struct zip_stat zstat;
- char buffer[32768];
- ssize_t sizr, sizw;
- size_t esize;
-
- /* open the zip file */
- zip = zip_open(zipfile, ZIP_CHECKCONS, &err);
- if (!zip) {
- syslog(LOG_ERR, "Can't connect to file %s", zipfile);
- return -1;
- }
-
- z64 = zip_get_num_entries(zip, 0);
- if (z64 < 0 || z64 > UINT_MAX) {
- syslog(LOG_ERR, "too many entries in %s", zipfile);
- goto error;
- }
- count = (unsigned int)z64;
-
- /* records the files */
- file_reset();
- esize = 0;
- for (index = 0 ; index < count ; index++) {
- err = zip_stat_index(zip, index, ZIP_FL_ENC_GUESS, &zstat);
- /* check the file name */
- if (!is_valid_filename(zstat.name)) {
- syslog(LOG_ERR, "invalid entry %s found in %s", zstat.name, zipfile);
- goto error;
- }
- if (zstat.name[0] == '/') {
- syslog(LOG_ERR, "absolute entry %s found in %s", zstat.name, zipfile);
- goto error;
- }
- len = strlen(zstat.name);
- if (len == 0) {
- syslog(LOG_ERR, "empty entry found in %s", zipfile);
- goto error;
- }
- if (zstat.size == 0) {
- /* directory name */
- if (zstat.name[len - 1] != '/') {
- syslog(LOG_ERR, "bad directory name %s in %s", zstat.name, zipfile);
- goto error;
- }
- /* record */
- fdesc = file_add_directory(zstat.name);
- } else {
- /* directory name */
- if (zstat.name[len - 1] == '/') {
- syslog(LOG_ERR, "bad file name %s in %s", zstat.name, zipfile);
- goto error;
- }
- /* get the size */
- esize += zstat.size;
- /* record */
- fdesc = file_add_file(zstat.name);
- }
- if (!fdesc)
- goto error;
- fdesc->zindex = index;
- }
-
- /* check the size */
- if (maxsize && esize > maxsize) {
- syslog(LOG_ERR, "extracted size %zu greater than allowed size %llu", esize, maxsize);
- goto error;
- }
-
- /* unpack the recorded files */
- assert(count == file_count());
- for (index = 0 ; index < count ; index++) {
- fdesc = file_of_index(index);
- assert(fdesc != NULL);
- err = zip_stat_index(zip, fdesc->zindex, ZIP_FL_ENC_GUESS, &zstat);
- assert(zstat.name[0] != '/');
- if (zstat.size == 0) {
- /* directory name */
- err = create_directory((char*)zstat.name, MODE_OF_DIRECTORY_CREATION);
- if (err && errno != EEXIST)
- goto error;
- } else {
- /* file name */
- zfile = zip_fopen_index(zip, fdesc->zindex, 0);
- if (!zfile) {
- syslog(LOG_ERR, "Can't open %s in %s", zstat.name, zipfile);
- goto error;
- }
- fd = create_file((char*)zstat.name, MODE_OF_FILE_CREATION, MODE_OF_DIRECTORY_CREATION);
- if (fd < 0)
- goto errorz;
- /* extract */
- z64 = zstat.size;
- while (z64) {
- sizr = zip_fread(zfile, buffer, sizeof buffer);
- if (sizr < 0) {
- syslog(LOG_ERR, "error while reading %s in %s", zstat.name, zipfile);
- goto errorzf;
- }
- sizw = write(fd, buffer, sizr);
- if (sizw < 0) {
- syslog(LOG_ERR, "error while writing %s", zstat.name);
- goto errorzf;
- }
- z64 -= sizw;
- }
- close(fd);
- zip_fclose(zfile);
- }
- }
-
- zip_close(zip);
- return 0;
-
-errorzf:
- close(fd);
-errorz:
- zip_fclose(zfile);
-error:
- zip_close(zip);
- return -1;
-}
-
-struct zws {
- struct zip *zip;
- char name[PATH_MAX];
- char buffer[32768];
-};
-
-static int zwr(struct zws *zws, int offset)
-{
- int len, err;
- DIR *dir;
- struct dirent *ent;
- zip_int64_t z64;
- struct zip_source *zsrc;
-
- if (offset == 0)
- dir = opendir(".");
- else {
- dir = opendir(zws->name);
- zws->name[offset++] = '/';
- }
- if (!dir) {
- syslog(LOG_ERR, "opendir %.*s failed in zwr", offset, zws->name);
- return -1;
- }
-
- ent = readdir(dir);
- while (ent != NULL) {
- len = strlen(ent->d_name);
- if (ent->d_name[0] == '.' && (len == 1 ||
- (ent->d_name[1] == '.' && len == 2)))
- ;
- else if (offset + len >= sizeof(zws->name)) {
- syslog(LOG_ERR, "name too long in zwr");
- errno = ENAMETOOLONG;
- goto error;
- } else {
- memcpy(zws->name + offset, ent->d_name, 1+len);
- if (!is_valid_filename(ent->d_name)) {
- syslog(LOG_ERR, "invalid name %s", zws->name);
- goto error;
- }
- switch (ent->d_type) {
- case DT_DIR:
- z64 = zip_dir_add(zws->zip, zws->name, ZIP_FL_ENC_UTF_8);
- if (z64 < 0) {
- syslog(LOG_ERR, "zip_dir_add of %s failed", zws->name);
- goto error;
- }
- err = zwr(zws, offset + len);
- if (err)
- goto error;
- break;
- case DT_REG:
- zsrc = zip_source_file(zws->zip, zws->name, 0, 0);
- if (zsrc == NULL) {
- syslog(LOG_ERR, "zip_source_file of %s failed", zws->name);
- goto error;
- }
- z64 = zip_file_add(zws->zip, zws->name, zsrc, ZIP_FL_ENC_UTF_8);
- if (z64 < 0) {
- syslog(LOG_ERR, "zip_file_add of %s failed", zws->name);
- zip_source_free(zsrc);
- goto error;
- }
- break;
- default:
- break;
- }
- }
- ent = readdir(dir);
- }
-
- closedir(dir);
- return 0;
-error:
- closedir(dir);
- return -1;
-}
-
-/* write (pack) content of the current directory in 'zipfile' */
-int zwrite(const char *zipfile)
-{
- int err;
- struct zws zws;
-
- zws.zip = zip_open(zipfile, ZIP_CREATE|ZIP_TRUNCATE, &err);
- if (!zws.zip) {
- syslog(LOG_ERR, "Can't open %s for write", zipfile);
- return -1;
- }
-
- err = zwr(&zws, 0);
- zip_close(zws.zip);
- return err;
-}
-
-
-#if defined(TEST_READ)
-int main(int ac, char **av)
-{
- for(av++ ; *av ; av++)
- zread(*av);
- return 0;
-}
-#endif
-
-#if defined(TEST_WRITE)
-int main(int ac, char **av)
-{
- for(av++ ; *av ; av++)
- zwrite(*av);
- return 0;
-}
-#endif
-