SDL_RWops *SDL_RWFromZIP(const char* archivename, const char* filename)
{
    SDL_RWops* rwops;
    struct zip* zarchive;
    struct zip_file* zfile;
    int errorp = 0;

    zarchive = zip_open(archivename, ZIP_CHECKCONS, &errorp);
    if (errorp != 0)
      {
	char *errorbuf = NULL;
	int len = 1;
	errorbuf = malloc(len);
	len = zip_error_to_str(errorbuf, len, errorp, errno);
	errorbuf = realloc(errorbuf, len + 1);
	len = zip_error_to_str(errorbuf, len, errorp, errno);
	log_warn("zip_open: %s", errorbuf);
	free(errorbuf);
	return NULL;
      }
    zfile = zip_fopen(zarchive, filename, 0);
    if (zfile == NULL)
      {
	log_error("zip_open: %s", zip_strerror(zarchive));
	zip_close(zarchive);
	return NULL;
      }

    /* libzip does not support seek()ing in file, so we can't use it -
       TTF_OpenFontRW needs it to read data at the end of files.  */
#if 0
    rwops = SDL_AllocRW();
    if (rwops == NULL)
      { errno=ENOMEM;
	zip_close(zarchive);
	return NULL;
      }

    rwops->hidden.unknown.data1 = zfile;
    rwops->read = rwops_libzip_read;
    rwops->write = rwops_libzip_write;
    rwops->seek = rwops_libzip_seek;
    rwops->close = rwops_libzip_close;
    return rwops;
#endif

    struct zip_stat zfilestat;
    if (zip_stat(zarchive, filename, 0, &zfilestat) < 0)
      {
	log_warn("zip_open: %s", zip_strerror(zarchive));
	zip_close(zarchive);
	return NULL;
      }

    char *content = malloc(zfilestat.size);
    zip_fread(zfile, content, zfilestat.size);
    rwops = SDL_RWFromMem(content, zfilestat.size);
    zip_fclose(zfile);
    zip_close(zarchive);

    return rwops;
}
Beispiel #2
0
AbstractFSProvider::status_t ZIPProvider::ZIPHandle::dir(
															const std::string & localDirectory,
															std::list<FileName> & result,
															const uint8_t flags) {
	int num = zip_get_num_files(handle);
	if (num == -1) {
		WARN(zip_strerror(handle));
		return FAILURE;
	}
	struct zip_stat sb;
	zip_stat_init(&sb);

	// Iterate over indices.
	for (int i = 0; i < num; ++i) {
		if (zip_stat_index(handle, i, 0, &sb) == -1) {
			WARN(zip_strerror(handle));
			return FAILURE;
		}

		FileName entryFileName(sb.name);

		// Determine if the entry is a file or a directory.
		if (entryFileName.getFile().empty()) {
			if(!(flags & FileUtils::DIR_DIRECTORIES)) {
				continue;
			}

			if (!(flags & FileUtils::DIR_RECURSIVE)) {
				std::string entryDirectory = entryFileName.getDir();

				if(entryDirectory == localDirectory) {
					continue;
				}

				if(entryDirectory.back() == '/') {
					entryDirectory.resize(entryDirectory.size() - 1);
				}
				const auto slashPos = entryDirectory.find_last_of('/');
				if(slashPos != std::string::npos) {
					entryDirectory = entryDirectory.substr(0, slashPos + 1);
				} else {
					entryDirectory.clear();
				}
				// Compare the parent directory of the directory with the requested localDirectory.
				if(entryDirectory != localDirectory) {
					continue;
				}
			}
		} else {
			if(!(flags & FileUtils::DIR_FILES)) {
				continue;
			}

			// Compare the directory of the file with the requested localDirectory.
			if (!(flags & FileUtils::DIR_RECURSIVE) && entryFileName.getDir() != localDirectory) {
				continue;
			}
		}

		// Check for hidden files beginning with '.' (files only).
		if (entryFileName.getFile().front() == '.' && !(flags & FileUtils::DIR_HIDDEN_FILES)) {
			continue;
		}

		FileName f;
		f.setFSName(archiveRoot.getFSName());
		f.setDir(archiveRoot.getDir() + entryFileName.getDir());
		f.setFile(entryFileName.getFile());
		result.push_back(f);
	}
	return OK;
}
Beispiel #3
0
struct input_file *read_file_list (int argc, char **argv,
                                   int *nf_r, char *errstr) {
  struct input_file *list = (struct input_file *) NULL;

  FILE *fp = (FILE *) NULL;
  char line[16384], *av, *p, *s;

  int a, f, nf = 0;

#ifndef _WIN32
  glob_t gbuf;
  int rv, op;

  /* Init */
  gbuf.gl_pathv = (char **) NULL;
#endif

  int is_zip;

#ifdef ZIPSUPPORT
  zip_t *z = (zip_t *) NULL;
  zip_error_t ze;
  struct zip_stat sb;

  int zerrno;
  int ent, nent;
  const char *name;
  int namelen;

  zip_uint8_t opsys;
  zip_uint32_t extattr;
#endif

  /* Loop over arguments */
  for(a = 0; a < argc; a++) {
    av = argv[a];

    if(*av == '@') {  /* @list form */
      av++;  /* skip past the @ */

      is_zip = is_zip_file(av, errstr);
      if(is_zip < 0)
        goto error;

      if(is_zip) {
#ifdef ZIPSUPPORT
        z = zip_open(av, 0, &zerrno);
        if(!z) {
          zip_error_init_with_code(&ze, zerrno);
          report_err(errstr, "zip_open: %s: %s",
                     av, zip_error_strerror(&ze));
          zip_error_fini(&ze);
          goto error;
        }
        
        nent = zip_get_num_entries(z, 0);
        if(nent < 0) {
          report_err(errstr, "zip_get_num_entries: %s",
                     zip_strerror(z));
          goto error;
        }
        
        for(ent = 0; ent < nent; ent++) {
          if(zip_stat_index(z, ent, 0, &sb)) {
            report_err(errstr, "zip_stat_index(%d): %s\n",
                       ent, zip_strerror(z));
            goto error;
          }
          
          if(zip_file_get_external_attributes(z, ent, 0, &opsys, &extattr)) {
            report_err(errstr, "zip_get_external_attributes(%d): %s\n",
                       ent, zip_strerror(z));
            goto error;
          }
          
          name = sb.name;
          namelen = strlen(name);
          
          if((opsys != ZIP_OPSYS_AMIGA && extattr & 0x10) ||
             (namelen > 0 && name[namelen-1] == '/'))
            /* Is directory */
            continue;
          
          /* Otherwise, add to list */
          list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
          if(!list) {
            report_syserr(errstr, "realloc");
            goto error;
          }
          
          s = strdup(name);
          if(!s) {
            report_syserr(errstr, "strdup");
            goto error;
          }
          
          list[nf].filename = s;
          list[nf].ient = ent;
          list[nf].iarg = a;
          list[nf].arg = av;
          nf++;
        }
        
        if(zip_close(z)) {
          report_err(errstr, "zip_close: %s",
                     zip_strerror(z));
          goto error;
        }

        z = (zip_t *) NULL;
#else
        report_err(errstr, "not compiled with zip support");
        goto error;
#endif
      }
      else {
        fp = fopen(av, "r");
        if(!fp) {
          report_syserr(errstr, "open: %s", av);
          goto error;
        }
        
        while(fgets(line, sizeof(line), fp)) {
          p = sstrip(line);
          
          if(*p) {
            list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
            if(!list) {
              report_syserr(errstr, "realloc");
              goto error;
            }
            
            s = strdup(p);
            if(!s) {
              report_syserr(errstr, "strdup");
              goto error;
            }
            
            list[nf].filename = s;
            list[nf].ient = -1;
            list[nf].iarg = a;
            list[nf].arg = av;
            nf++;
          }
        }
        
        if(ferror(fp)) {
          report_syserr(errstr, "read: %s", av);
          goto error;
        }
        
        fclose(fp);
        fp = (FILE *) NULL;
      }
    }
    else {  /* glob or single filename */
#ifndef _WIN32
      rv = glob(av, 0, NULL, &gbuf);
      if(rv == 0) {  /* succeeded */
        /* Allocate block */
        list = (struct input_file *) realloc(list,
                                             (nf+gbuf.gl_pathc) * sizeof(struct input_file));
        if(!list) {
          report_syserr(errstr, "realloc");
          goto error;
        }

        /* Zero out the new pointers */
        memset(list+nf, 0, gbuf.gl_pathc * sizeof(struct input_file));

        /* Record so we know to free them */
        op = nf;

        nf += gbuf.gl_pathc;
        
        for(f = 0; f < gbuf.gl_pathc; f++) {
          s = strdup(gbuf.gl_pathv[f]);
          if(!s) {
            report_syserr(errstr, "strdup");
            goto error;
          }

          list[op].filename = s;
          list[op].ient = -1;
          list[op].iarg = a;
          list[op].arg = av;
          op++;
        }

        globfree(&gbuf);
        gbuf.gl_pathv = (char **) NULL;
      }
      else if(rv == GLOB_NOMATCH) {  /* no match */
#endif  /* _WIN32 */

        /* Assume it's a single entry. */
        list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
        if(!list) {
          report_syserr(errstr, "realloc");
          goto error;
        }
        
        s = strdup(av);
        if(!s) {
          report_syserr(errstr, "strdup");
          goto error;
        }
        
        list[nf].filename = s;
        list[nf].ient = -1;
        list[nf].iarg = a;
        list[nf].arg = av;
        nf++;
#ifndef _WIN32
      }
      else {
        report_err(errstr, "glob error: %s", av);
        goto error;
      }
#endif
    }
  }

  *nf_r = nf;

  return(list);

 error:
  if(fp)
    fclose(fp);

#ifndef _WIN32
  if(gbuf.gl_pathv)
    globfree(&gbuf);
#endif

#ifdef ZIPSUPPORT
  if(z) {
    zip_close(z);
    z = (zip_t *) NULL;
  }
#endif

  if(list) {
    for(f = 0; f < nf; f++)
      if(list[f].filename)
        free((void *) list[f].filename);

    free((void *) list);
  }

  return((struct input_file *) NULL);
}
Beispiel #4
0
/* zipfile.replaceFile(nameInArchive, name, offset, len) */
Handle<Value> ZipFile::Replace_File(const Arguments& args)
{
    ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This());

    struct zip_source *source;

    if (zf->Busy())
      return ThrowException(Exception::Error(String::New("Zipfile already in use..")));

    if (!args[0]->IsString())
      return ThrowException(Exception::TypeError(
                 String::New("Argument must be a file name.")));
    std::string archive_file = TOSTR(args[0]);

    std::string name;
    if (args[1]->IsUndefined())
      name = archive_file;
    else
      if (!args[1]->IsString())
        return ThrowException(Exception::TypeError(
                   String::New("Argument must be a file name.")));
      name = TOSTR(args[1]);

    zip_int64_t off;
    if (args[2]->IsUndefined())
      off = 0;
    else
      off = args[2]->Int32Value();
    
    zip_int64_t len; 
    if (args[3]->IsUndefined()) 
      len = -1; 
    else 
      len = args[3]->Int32Value();

    int idx = -1;
    
    std::vector<std::string>::iterator it = std::find(zf->names.begin(), zf->names.end(), archive_file);
    if (it!=zf->names.end()) {
        idx = distance(zf->names.begin(), it);
    }

    if (idx == -1) {
        std::stringstream s;
        s << "No file found by the name of: '" << archive_file << "\n";
        return ThrowException(Exception::Error(String::New(s.str().c_str())));
    }

    source = zip_source_file(zf->archive, name.c_str(), off, len);
    if (source == NULL) {
      std::stringstream s;
      s << "Error while replacing file " << name << " in zip archive: " << zip_strerror(zf->archive) << "\n";
      return ThrowException(Exception::Error(String::New(s.str().c_str())));
    }

    int ret = zip_replace(zf->archive, idx, source);        
    if (ret < 0) {
      zip_source_free(source);
      std::stringstream s;
      s << "Error while replacing file " << name << " in zip archive: " << zip_strerror(zf->archive) << "\n";
      return ThrowException(Exception::Error(String::New(s.str().c_str())));
    }

    return Undefined();
}
Beispiel #5
0
ZIPProvider::ZIPHandle::~ZIPHandle() {
	if (zip_close(handle) == -1) {
		WARN(zip_strerror(handle));
	}
}
Beispiel #6
0
Handle<Value> ZipFile::readFileSync(const Arguments& args)
{
    HandleScope scope;

    if (args.Length() != 1 || !args[0]->IsString())
        return ThrowException(Exception::TypeError(
          String::New("first argument must be a file name inside the zip")));

    std::string name = TOSTR(args[0]);
  
    // TODO - enforce valid index
    ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This());

    if (zf->Busy())
      return ThrowException(Exception::Error(String::New("Zipfile already in use..")));

    struct zip_file *zf_ptr;

    int idx = -1;
    
    std::vector<std::string>::iterator it = std::find(zf->names.begin(), zf->names.end(), name);
    if (it!=zf->names.end()) {
        idx = distance(zf->names.begin(), it);
    }

    if (idx == -1) {
        std::stringstream s;
        s << "No file found by the name of: '" << name << "\n";
        return ThrowException(Exception::Error(String::New(s.str().c_str())));
    }

    if ((zf_ptr=zip_fopen_index(zf->archive, idx, 0)) == NULL) {
        zip_fclose(zf_ptr);
        std::stringstream s;
        s << "cannot open file #" << idx << " in " << name << ": archive error: " << zip_strerror(zf->archive) << "\n";
        return ThrowException(Exception::Error(String::New(s.str().c_str())));
    }

    struct zip_stat st;
    zip_stat_index(zf->archive, idx, 0, &st);
  
    std::vector<unsigned char> data;
    data.clear();
    data.resize( st.size );
    
    int result =  0;
    result = (int)zip_fread( zf_ptr, reinterpret_cast<void*> (&data[0]), data.size() );

    if (result < 0) {
        zip_fclose(zf_ptr);
        std::stringstream s;
        s << "error reading file #" << idx << " in " << name << ": archive error: " << zip_file_strerror(zf_ptr) << "\n";
        return ThrowException(Exception::Error(String::New(s.str().c_str())));
    }

    #if NODE_VERSION_AT_LEAST(0,3,0)
        node::Buffer *retbuf = Buffer::New((char *)&data[0],data.size());
    #else
        node::Buffer *retbuf = Buffer::New(data.size());
        std::memcpy(retbuf->data(), (char *)&data[0], data.size());
    #endif
    
    zip_fclose(zf_ptr);
    return scope.Close(retbuf->handle_);
}
Beispiel #7
0
Handle<Value> ZipFile::Open(const Arguments& args)
{
    if (args.Length() != 1 || !args[0]->IsString())
        return ThrowException(Exception::TypeError(
          String::New("Argument must be a file name inside the zip")));

    std::string name = TOSTR(args[0]);
  
    // TODO - enforce valid index
    ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This());

    if (zf->Busy())
      return ThrowException(Exception::Error(String::New("Zipfile already in use..")));

    zf->file_index = -1;

    std::vector<std::string>::iterator it = std::find(zf->names.begin(), zf->names.end(), name);
    if (it!=zf->names.end()) {
        zf->file_index = distance(zf->names.begin(), it);
    }

    if (zf->file_index == -1) {
        std::stringstream s;
        s << "No file found by the name of: '" << name << "\n";
        return ThrowException(Exception::Error(String::New(s.str().c_str())));
    }

    if ((zf->file=zip_fopen_index(zf->archive, zf->file_index, 0)) == NULL) {
        zip_fclose(zf->file);
        zf->file = NULL;
        std::stringstream s;
        s << "cannot open file #" << zf->file_index << " in " << name << ": archive error: " << zip_strerror(zf->archive) << "\n";
        return ThrowException(Exception::Error(String::New(s.str().c_str())));
    }

    return Undefined();
}
Beispiel #8
0
void print_zip_err(const char *prefix, zip_t *zip) {
    char buffer[1024];
    snprintf(buffer, 1024, "%s: %s\n", prefix, zip_strerror(zip));
    engine_print(buffer);
}
Beispiel #9
0
int session_save(char *filename)
{
	GSList *l, *d;
	struct device *device;
	struct datastore *ds;
	struct zip *zipfile;
	struct zip_source *src;
	int bufcnt, devcnt, tmpfile, ret, error;
	char version[1], rawname[16], metafile[32], *buf;

	/* Quietly delete it first, libzip wants replace ops otherwise. */
	unlink(filename);

	if (!(zipfile = zip_open(filename, ZIP_CREATE, &error)))
		return SIGROK_ERR;

	/* Version */
	version[0] = '1';
	if (!(src = zip_source_buffer(zipfile, version, 1, 0)))
		return SIGROK_ERR;
	if (zip_add(zipfile, "version", src) == -1) {
		g_message("error saving version into zipfile: %s",
			  zip_strerror(zipfile));
		return SIGROK_ERR;
	}

	/* Metadata */
	strcpy(metafile, "sigrok-meta-XXXXXX");
	if ((tmpfile = g_mkstemp(metafile)) == -1)
		return SIGROK_ERR;
	close(tmpfile);
	make_metadata(metafile);
	if (!(src = zip_source_file(zipfile, metafile, 0, -1)))
		return SIGROK_ERR;
	if (zip_add(zipfile, "metadata", src) == -1)
		return SIGROK_ERR;
	unlink(metafile);

	/* Raw */
	devcnt = 1;
	for (l = session->devices; l; l = l->next) {
		device = l->data;
		ds = device->datastore;
		if (ds) {
			buf = malloc(ds->num_units * ds->ds_unitsize +
				   DATASTORE_CHUNKSIZE);
			bufcnt = 0;
			for (d = ds->chunklist; d; d = d->next) {
				memcpy(buf + bufcnt, d->data,
				       DATASTORE_CHUNKSIZE);
				bufcnt += DATASTORE_CHUNKSIZE;
			}
			if (!(src = zip_source_buffer(zipfile, buf,
				       ds->num_units * ds->ds_unitsize, TRUE)))
				return SIGROK_ERR;
			snprintf(rawname, 15, "raw-%d", devcnt);
			if (zip_add(zipfile, rawname, src) == -1)
				return SIGROK_ERR;
		}
		devcnt++;
	}

	if ((ret = zip_close(zipfile)) == -1) {
		g_message("error saving zipfile: %s", zip_strerror(zipfile));
		return SIGROK_ERR;
	}

	return SIGROK_OK;
}
Beispiel #10
0
int
main(int argc, char *argv[])
{
    int fail, ze;
    int c;
    struct zip *z;
    struct zip_source *zs;
    char *archive;
    char errstr[1024];

    verbose = 0;
    fail = 0;

    prg = argv[0];

    while ((c=getopt(argc, argv, "v")) != -1) {
	switch (c) {
            case 'v':
                verbose = 1;
                break;

            default:
                fprintf(stderr, usage, prg);
                return 1;
	}
    }

    
    if (argc-optind != 1) {
        fprintf(stderr, usage, prg);
        return 1;
    }

    archive = argv[optind];

    if ((z=zip_open(archive, 0, &ze)) == NULL) {
	zip_error_to_str(errstr, sizeof(errstr), ze, errno);
	printf("%s: can't open zip archive '%s': %s\n",
	       prg, archive, errstr);
	return 1;
    }

    fail += do_read(z, "storedok", 0, WHEN_NEVER, 0, 0);
    fail += do_read(z, "deflateok", 0, WHEN_NEVER, 0, 0);
    fail += do_read(z, "storedcrcerror", 0, WHEN_READ, ZIP_ER_CRC, 0);
    fail += do_read(z, "deflatecrcerror", 0, WHEN_READ, ZIP_ER_CRC, 0);
    fail += do_read(z, "deflatezliberror", 0, WHEN_READ, ZIP_ER_ZLIB, -3);
    fail += do_read(z, NULL, 0, WHEN_OPEN, ZIP_ER_INVAL, 0);
    fail += do_read(z, "nosuchfile", 0, WHEN_OPEN, ZIP_ER_NOENT, 0);
    fail += do_read(z, "deflatezliberror", ZIP_FL_COMPRESSED, WHEN_NEVER, 0,0);
    fail += do_read(z, "deflatecrcerror", ZIP_FL_COMPRESSED, WHEN_NEVER, 0, 0);
    fail += do_read(z, "storedcrcerror", ZIP_FL_COMPRESSED,
		    WHEN_READ, ZIP_ER_CRC, 0);
    fail += do_read(z, "storedok", ZIP_FL_COMPRESSED, WHEN_NEVER, 0, 0);

    fail += do_read(z, "cryptok", 0, WHEN_OPEN, ZIP_ER_NOPASSWD, 0);
    zip_set_default_password(z, "crypt");
    fail += do_read(z, "cryptok", 0, WHEN_NEVER, 0, 0);
    zip_set_default_password(z, "wrong");
    fail += do_read(z, "cryptok", 0, WHEN_OPEN, ZIP_ER_WRONGPASSWD, 0);
    zip_set_default_password(z, NULL);

    zs = zip_source_buffer(z, "asdf", 4, 0);
    zip_replace(z, zip_name_locate(z, "storedok", 0), zs);
    fail += do_read(z, "storedok", 0, WHEN_OPEN, ZIP_ER_CHANGED, 0);
    fail += do_read(z, "storedok", ZIP_FL_UNCHANGED, WHEN_NEVER, 0, 0);
    zip_delete(z, zip_name_locate(z, "storedok", 0));
    fail += do_read(z, "storedok", 0, WHEN_OPEN, ZIP_ER_NOENT, 0);
    fail += do_read(z, "storedok", ZIP_FL_UNCHANGED, WHEN_NEVER, 0, 0);
    zs = zip_source_buffer(z, "asdf", 4, 0);
    if (zip_file_add(z, "new_file", zs, 0) < 0)
        fprintf(stderr, "%s: can't add file to zip archive '%s': %s\n", prg, archive, zip_strerror(z));
    fail += do_read(z, "new_file", 0, WHEN_OPEN, ZIP_ER_CHANGED, 0);
    zip_unchange_all(z);

    if (zip_close(z) == -1) {
        fprintf(stderr, "%s: can't close zip archive '%s': %s\n", prg, archive, zip_strerror(z));
        return 1;
    }

    exit(fail ? 1 : 0);
}