示例#1
0
void KeyValue::modify_zip_file_test() throw (KeyValueException) {
    if (is_zip_file()) {
        throw KeyValueException("A packaged file can't be modified.");
    }
}
示例#2
0
const osd_directory_entry *zippath_readdir(zippath_directory *directory)
{
	const osd_directory_entry *result = NULL;
	const zip_file_header *header;
	const char *relpath;
	const char *separator;
	const char *s;
	zippath_returned_directory *rdent;

	if (!directory->returned_parent)
	{
		/* first thing's first - return parent directory */
		directory->returned_parent = true;
		memset(&directory->returned_entry, 0, sizeof(directory->returned_entry));
		directory->returned_entry.name = "..";
		directory->returned_entry.type = ENTTYPE_DIR;
		result = &directory->returned_entry;
	}
	else if (directory->directory != NULL)
	{
		/* a normal directory read */
		do
		{
			result = osd_readdir(directory->directory);
		}
		while((result != NULL) && (!strcmp(result->name, ".") || !strcmp(result->name, "..")));

		/* special case - is this entry a ZIP file?  if so we need to return it as a "directory" */
		if ((result != NULL) && is_zip_file(result->name))
		{
			/* copy; but change the entry type */
			directory->returned_entry = *result;
			directory->returned_entry.type = ENTTYPE_DIR;
			result = &directory->returned_entry;
		}
	}
	else if (directory->zipfile != NULL)
	{
		do
		{
			/* a zip file read */
			do
			{
				if (!directory->called_zip_first)
					header = zip_file_first_file(directory->zipfile);
				else
					header = zip_file_next_file(directory->zipfile);
				directory->called_zip_first = true;
				relpath = NULL;
			}
			while((header != NULL) && ((relpath = get_relative_path(directory, header)) == NULL));

			if (relpath != NULL)
			{
				/* we've found a ZIP entry; but this may be an entry deep within the target directory */
				for (s = relpath; *s && !is_zip_file_separator(*s); s++)
					;
				separator = *s ? s : NULL;

				if (separator != NULL)
				{
					/* a nested entry; loop through returned_dirlist to see if we've returned the parent directory */
					for (rdent = directory->returned_dirlist; rdent != NULL; rdent = rdent->next)
					{
						if (!core_strnicmp(rdent->name.c_str(), relpath, separator - relpath))
							break;
					}

					if (rdent == NULL)
					{
						/* we've found a new directory; add this to returned_dirlist */
						rdent = new zippath_returned_directory;
						rdent->next = directory->returned_dirlist;
						rdent->name.assign(relpath, separator - relpath);
						directory->returned_dirlist = rdent;

						/* ...and return it */
						memset(&directory->returned_entry, 0, sizeof(directory->returned_entry));
						directory->returned_entry.name = rdent->name.c_str();
						directory->returned_entry.type = ENTTYPE_DIR;
						result = &directory->returned_entry;
					}
				}
				else
				{
					/* a real file */
					memset(&directory->returned_entry, 0, sizeof(directory->returned_entry));
					directory->returned_entry.name = relpath;
					directory->returned_entry.type = ENTTYPE_FILE;
					directory->returned_entry.size = header->uncompressed_length;
					result = &directory->returned_entry;
				}
			}
		}
		while((relpath != NULL) && (result == NULL));
	}
	return result;
}
示例#3
0
file_error zippath_fopen(const char *filename, UINT32 openflags, core_file *&file, std::string &revised_path)
{
	file_error filerr = FILERR_NOT_FOUND;
	zip_error ziperr;
	zip_file *zip = NULL;
	const zip_file_header *header;
	osd_dir_entry_type entry_type;
	char *alloc_fullpath = NULL;
	int len;

	/* first, set up the two types of paths */
	std::string mainpath(filename);
	std::string subpath;
	file = NULL;

	/* loop through */
	while((file == NULL) && (mainpath.length() > 0)
		&& ((openflags == OPEN_FLAG_READ) || (subpath.length() == 0)))
	{
		/* is the mainpath a ZIP path? */
		if (is_zip_file(mainpath.c_str()))
		{
			/* this file might be a zip file - lets take a look */
			ziperr = zip_file_open(mainpath.c_str(), &zip);
			if (ziperr == ZIPERR_NONE)
			{
				/* it is a zip file - error if we're not opening for reading */
				if (openflags != OPEN_FLAG_READ)
				{
					filerr = FILERR_ACCESS_DENIED;
					goto done;
				}

				if (subpath.length() > 0)
					header = zippath_find_sub_path(zip, subpath.c_str(), &entry_type);
				else
					header = zip_file_first_file(zip);

				if (header == NULL)
				{
					filerr = FILERR_NOT_FOUND;
					goto done;
				}

				/* attempt to read the file */
				filerr = create_core_file_from_zip(zip, header, file);
				if (filerr != FILERR_NONE)
					goto done;

				/* update subpath, if appropriate */
				if (subpath.length() == 0)
					subpath.assign(header->filename);

				/* we're done */
				goto done;
			}
		}
		else if (is_7z_file(mainpath.c_str()))
		{
			filerr = FILERR_INVALID_DATA;
			goto done;
		}

		if (subpath.length() == 0)
			filerr = core_fopen(filename, openflags, &file);
		else
			filerr = FILERR_NOT_FOUND;

		/* if we errored, then go up a directory */
		if (filerr != FILERR_NONE)
		{
			/* go up a directory */
			std::string temp;
			zippath_parent(temp, mainpath.c_str());

			/* append to the sub path */
			if (subpath.length() > 0)
			{
				std::string temp2;
				mainpath = mainpath.substr(temp.length());
				temp2.assign(mainpath).append(PATH_SEPARATOR).append(subpath);
				subpath.assign(temp2);
			}
			else 
			{
				mainpath = mainpath.substr(temp.length());
				subpath.assign(mainpath);
			}
			/* get the new main path, truncating path separators */
			len = temp.length();
			while (len > 0 && is_zip_file_separator(temp[len - 1]))
				len--;
			temp = temp.substr(0, len);
			mainpath.assign(temp);
		}
	}

done:
	/* store the revised path */
	revised_path.clear();
	if (filerr == FILERR_NONE)
	{
		/* cannonicalize mainpath */
		filerr = osd_get_full_path(&alloc_fullpath, mainpath.c_str());
		if (filerr == FILERR_NONE)
		{
			if (subpath.length() > 0)
				revised_path.assign(alloc_fullpath).append(PATH_SEPARATOR).append(subpath);
			else
				revised_path.assign(alloc_fullpath);
		}
	}

	if (zip != NULL)
		zip_file_close(zip);
	if (alloc_fullpath != NULL)
		osd_free(alloc_fullpath);
	return filerr;
}
示例#4
0
static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, zip_file *&zipfile, std::string &newpath)
{
	file_error err;
	osd_directory_entry *current_entry = NULL;
	osd_dir_entry_type current_entry_type;
	int went_up = FALSE;
	int i;

	newpath.clear();

	/* be conservative */
	entry_type = ENTTYPE_NONE;
	zipfile = NULL;

	std::string apath(path);
	std::string apath_trimmed;
	do
	{
		/* trim the path of trailing path separators */
		i = apath.length();
		while (i > 1 && is_path_separator(apath[i - 1]))
			i--;
		apath = apath.substr(0, i);
		apath_trimmed.assign(apath);

		/* stat the path */
		current_entry = osd_stat(apath_trimmed.c_str());

		/* did we find anything? */
		if (current_entry != NULL)
		{
			/* get the entry type and free the stat entry */
			current_entry_type = current_entry->type;
			osd_free(current_entry);
			current_entry = NULL;
		}
		else
		{
			/* if we have not found the file or directory, go up */
			current_entry_type = ENTTYPE_NONE;
			went_up = TRUE;
			std::string parent;
			apath.assign(zippath_parent(parent, apath.c_str()));
		}
	}
	while (current_entry_type == ENTTYPE_NONE && !is_root(apath.c_str()));

	/* if we did not find anything, then error out */
	if (current_entry_type == ENTTYPE_NONE)
	{
		err = FILERR_NOT_FOUND;
		goto done;
	}

	/* is this file a ZIP file? */
	if ((current_entry_type == ENTTYPE_FILE) && is_zip_file(apath_trimmed.c_str())
		&& (zip_file_open(apath_trimmed.c_str(), &zipfile) == ZIPERR_NONE))
	{
		i = strlen(path + apath.length());
		while (i > 0 && is_zip_path_separator(path[apath.length() + i - 1]))
			i--;
		newpath.assign(path + apath.length(), i);

		/* this was a true ZIP path - attempt to identify the type of path */
		zippath_find_sub_path(zipfile, newpath.c_str(), &current_entry_type);
		if (current_entry_type == ENTTYPE_NONE)
		{
			err = FILERR_NOT_FOUND;
			goto done;
		}
	}
	else
	{
		/* this was a normal path */
		if (went_up)
		{
			err = FILERR_NOT_FOUND;
			goto done;
		}
		newpath.assign(path);
	}

	/* success! */
	entry_type = current_entry_type;
	err = FILERR_NONE;

done:
	return err;
}
示例#5
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);
}