Пример #1
0
SgObject Sg_AbsolutePath(SgString *path)
{
  char buf[PATH_MAX];
  char *ret = realpath(Sg_Utf32sToUtf8s(path), buf);
  if (ret) {
    return Sg_Utf8sToUtf32s(buf, strlen(buf));
  }
  if (errno == ENOENT) {
    /* do some trick here */
    if (Sg_AbsolutePathP(path)) return normalise_path(path);
    return normalise_path(Sg_BuildPath(Sg_CurrentDirectory(), path));
  }
  return SG_FALSE;
}
Пример #2
0
std::string NormalisePath(const std::string &path)
{
    std::string result;
    result.reserve(path.size());
    normalise_path(result, StringRange(path.c_str(), path.size()));
    return result;
}
Пример #3
0
void  split_pathname(std::string const&  pathname, std::vector<std::string>& output)
{
    std::istringstream  istr(normalise_path(pathname));
    std::string  token;
    while (std::getline(istr,token,'/'))
        output.push_back(token);
}
Пример #4
0
	// Calculates the path of target relative to source.
	std::string compute_relative_path(const std::string& source, const std::string& target)
	{
		//std::cerr << "compute_relative_path(a): " << source << " : " << target << std::endl;
		std::string common_part = normalise_path(source);
		std::string back;
		if(common_part.length() > 1 && common_part[common_part.length()-1] == '/') {
			common_part.erase(common_part.length()-1);
		}
		while(boost::iequals(del_substring_front(target, common_part), target)) {
			size_t offs = common_part.rfind('/');
			//std::cerr << "compute_relative_path(b2): " << back << " : " << common_part << std::endl;
			if(common_part.length() > 1 && offs != std::string::npos) {
				common_part.erase(offs);
				back = "../" + back;
			} else {
				break;
			}
		}
		common_part = del_substring_front(target, common_part);
		if(common_part.length() == 1) {
			common_part = common_part.substr(1);
			if(back.empty() == false) {
				back.erase(back.length()-1);
			}
		} else if(common_part.length() > 1 && common_part[0] == '/') {
			common_part = common_part.substr(1);
		} else {
			if(back.empty() == false) {
				back.erase(back.length()-1);
			}
		}
		//std::cerr << "compute_relative_path(b): " << back << " : " << common_part << std::endl;
		return back + common_part;
	}
Пример #5
0
/* Intersect a userpath aperture with a path. Fill rule applied to aperture
   in NZFILL_TYPE, fill type applied to path is filltype. Note that makeconvex
   and cliptoall free their argument paths, so only the flattened paths
   need to be freed */
Bool path_in_path(PATHLIST *appath, PATHLIST *path, int32 filltype,
                  Bool *inside)
{
  PATHINFO apath, fpath ;

  if ( ! appath || ! path) { /* can't be inside a degenerate path */
    *inside = FALSE ;
    return TRUE ;
  }

  /* prepare both paths, using filltype for path and NZFILL for aperture */
  fl_setflat( theFlatness( theLineStyle(*gstateptr))) ;
  if ( ! path_flatten(appath, &apath) ||
       ! normalise_path(&apath, NZFILL_TYPE, FALSE, FALSE) )
    return FALSE ;

  if ( ! thePath(apath) ) {
    *inside = FALSE ;
    return TRUE ;
  }

  if ( ! path_flatten(path, &fpath) ||
       ! normalise_path(&fpath, filltype, FALSE, FALSE) ) {
    path_free_list(thePath(apath), mm_pool_temp) ;
    return FALSE ;
  }

  if ( ! thePath(fpath) ) {
    path_free_list(thePath(apath), mm_pool_temp) ;
    *inside = FALSE ;
    return TRUE ;
  }

  /* intersect aperture and path */
  if ( ! cliptoall(&apath, &fpath, &apath, FALSE) )
    return FALSE ;

  if ( thePath(apath) ) {
    *inside = TRUE ; /*  if it's not degenerate, aperture is painted */
    path_free_list(thePath(apath), mm_pool_temp) ;
  } else
    *inside = FALSE ; /* if clip is degenerate, it's not inside */

  return TRUE ;
}
Пример #6
0
std::string JoinPathBelow(const std::string &base, const std::string &path)
{
    if (base.empty())
        return path;
    if (!path.empty()) {
        if ((path[0] == '/') && (base != "/"))
            throw std::invalid_argument(path);
        else {
            std::string result(base);
            result.reserve(result.size() + 1 + path.size());
            if (result[result.size()-1] != '/')
                result += '/';
            StringRange rhs(path.c_str(), path.size());
            if (path[0] == '/') {
                assert(base == "/");
                ++rhs.begin;
            }
            normalise_path(result, rhs);
            return result;
        }
    } else
        return base;
}
Пример #7
0
std::pair<file_props_ptr,mach_header_props>
load_mach_file_props(std::string const&  mach_file, std::ifstream&  mach,
                     load_props_mach&  load_props, std::string& error_message)
{
    if (file_size(mach_file) < 4ULL)
    {
        error_message = NOT_MACH_FILE();
        return {};
    }

    bool const is_file_in_big_endian = false; // MACH file is stored in big-endian by default.
    bool const  is_it_load_of_root_binary = load_props.root_file() == mach_file;

    // We read magic number in order to reconse the file type (is it MACH or not).

    uint8_t  num_address_bits = 0U;
    {
        uint32_t const  magic = read_bytes_to_int32_t(mach,4U,is_file_in_big_endian);
        if (magic == 0xfeedfaceU) // Mach-O 32 bit
            num_address_bits = 32U;
        else if (magic == 0xfeedfacfU)  // Mach-O 64 bit
            num_address_bits = 64U;
        else if (magic == 0xcafebabeU)  // FAT binary
        {
            error_message = "Mac OS fat binaries are NOT IMPLEMENTED YET!";
            return {};
        }
        else
        {
            error_message = NOT_MACH_FILE();
            return {};
        }
    }

    // Now we read the rest of the header

    uint32_t const  cpu_type = read_bytes_to_int32_t(mach,4U,is_file_in_big_endian);

    //uint32_t const  cpu_subtype = read_bytes_to_int32_t(mach,4U,is_file_in_big_endian);
    skip_bytes(mach,4U); // We ignore cpu-sub-type.

    if ((num_address_bits == 64U && cpu_type != 0x1000007) ||
        (num_address_bits == 32U && cpu_type != 0x7) )
    {
        error_message = "Unsupported processor architecture.";
        return {};
    }

    architecture_t const arch = num_address_bits == 32U ? architecture_t::X86_32 :
                                                          architecture_t::X86_64 ;
    abi_t const abi = abi_t::DARWIN;

    platform_ptr const  file_platform{ new platform(arch, abi) };

    uint32_t const  filetype = read_bytes_to_int32_t(mach,4U,is_file_in_big_endian);

    if (filetype != 0x2U && filetype != 0x3U && filetype != 0x6U)
    {
        error_message = "The loaded Mach-O file is neither executable nor dynamic library.";
        return {};
    }

    bool const  is_dynamic_library = filetype == 0x3U || filetype == 0x6U;
    bool const  is_fixed_dynamic_library = filetype == 0x3U;

    uint32_t const  num_load_commnads = read_bytes_to_int32_t(mach,4U,is_file_in_big_endian);

    if (num_load_commnads == 0U)
    {
        error_message = "There is no load command in the binary.";
        return {};
    }

    uint32_t const  total_num_commnad_bytes = read_bytes_to_int32_t(mach,4U,is_file_in_big_endian);

    if (total_num_commnad_bytes < num_load_commnads * (num_address_bits / 8U))
    {
        error_message = "The list of load commands is too short.";
        return {};
    }

    skip_bytes(mach,4ULL); // We ignore flags.

    if (num_address_bits == 64U)
        skip_bytes(mach,4ULL); // We skip the reserved word.

    if ((uint64_t)mach.tellg() + (uint64_t)total_num_commnad_bytes >= (uint64_t)file_size(mach_file))
    {
        error_message = "The list of load commands goes beyond the end of the file.";
        return {};
    }

    // Next we create file properties data structure and we return results.

    static uint32_t file_id_generator = 0U;  // TODO: This is not an ideal implementation: move it to load_props.
    file_props_ptr const  mach_props { new file_props{
            normalise_path(absolute_path(mach_file)),
            format::MACH(),
            is_file_in_big_endian,
            num_address_bits,
            ++file_id_generator
            }};
    set_file_property(mach_props->property_map(), file_properties::file_type(),
                      is_dynamic_library ? file_types::library() : file_types::executable());

    load_props.add_file_props(mach_props);

    if (is_it_load_of_root_binary)
        load_props.set_platform( file_platform );
    if (*file_platform != *load_props.platform())
    {
        error_message = "Incompatible platforms of the executable and its shared library: " + mach_props->path();
        return {};
    }

    return {mach_props,std::make_tuple(num_load_commnads,total_num_commnad_bytes,is_fixed_dynamic_library)};
}
Пример #8
0
static int do_loadenv(int argc, char *argv[])
{
	char *filename = NULL, *dirname;
	unsigned flags = 0;
	int opt;
	int scrub = 0;
	int defaultenv = 0;

	while ((opt = getopt(argc, argv, "nsd")) > 0) {
		switch (opt) {
		case 'n':
			flags |= ENV_FLAG_NO_OVERWRITE;
			break;
		case 's':
			scrub = 1;
			break;
		case 'd':
			defaultenv = 1;
			break;
		default:
			return COMMAND_ERROR_USAGE;
		}
	}

	if (argc - optind < 2)
		dirname = "/env";
	else
		dirname = argv[optind + 1];

	if (argc - optind < 1) {
		filename = default_environment_path_get();
	} else {
		char *str = normalise_path(argv[optind]);

		/*
		 * /dev/defaultenv use to contain the defaultenvironment.
		 * we do not have this file anymore, but maintain compatibility
		 * to the 'loadenv -s /dev/defaultenv' command to restore the
		 * default environment for some time.
		 */
		if (!strcmp(str, "/dev/defaultenv"))
			defaultenv = 1;
		else
			filename = argv[optind];

		free(str);
	}

	if (scrub) {
		int ret;

		ret = unlink_recursive(dirname, NULL);
		if (ret && ret != -ENOENT) {
			eprintf("cannot remove %s: %s\n", dirname,
					strerror(-ret));
			return 1;
		}

		ret = mkdir(dirname, 0);
		if (ret) {
			eprintf("cannot create %s: %s\n", dirname,
					strerror(-ret));
			return ret;
		}
	}

	printf("loading environment from %s\n", defaultenv ? "defaultenv" : filename);

	if (defaultenv)
		return defaultenv_load(dirname, flags);
	else
		return envfs_load(filename, dirname, flags);
}
Пример #9
0
file_props_ptr  load_elf_file_props(std::string const&  elf_file, std::ifstream&  elf,
                                    load_props_elf&  load_props, std::string& error_message)
{
    if (file_size(elf_file) < 6ULL)
    {
        error_message = NOT_ELF_FILE();
        return file_props_ptr();
    }

    char magic[4U];
    elf.read(magic,4U);

    if (magic[0] != 0x7F ||
        magic[1] != 'E' ||
        magic[2] != 'L' ||
        magic[3] != 'F' )
    {
        error_message = NOT_ELF_FILE();
        return file_props_ptr();
    }

    elf.seekg(0x05ULL);
    uint8_t  endian_mode = ::read_byte(elf);
    if (endian_mode != 1 && endian_mode != 2)
    {
        elf.seekg(0x10ULL);
        uint32_t const  binary_type_little_endian = ::read_bytes_to_uint32_t(elf,2U,false);
        elf.seekg(0x10ULL);
        uint32_t const  binary_type_big_endian = ::read_bytes_to_uint32_t(elf,2U,true);
        bool const  little_cond = binary_type_little_endian == 2U || binary_type_little_endian == 3U;
        bool const  big_cond = binary_type_big_endian == 2U || binary_type_big_endian == 3U;
        if (little_cond && !big_cond)
        {
            endian_mode =  1U;
            LOAD_ELF_WARNING_IN(
                        elf_file,
                        "[Header offset 0x05] Unknown type of endian mode (neither little nor big). "
                        "The little endian was deduced form 2 bytes at the offset 0x10."
                        );
        }
        else if (!little_cond && big_cond)
        {
            endian_mode =  2U;
            LOAD_ELF_WARNING_IN(
                        elf_file,
                        "[Header offset 0x05] Unknown type of endian mode (neither little nor big). "
                        "The big endian was deduced form 2 bytes at the offset 0x10."
                        );
        }
        else
        {
            error_message = "[Header offset 0x05] Unknown type of endian mode (neither little nor big).";
            return file_props_ptr();
        }
    }
    bool const is_file_in_big_endian = endian_mode == 1 ? false : true;

    elf.seekg(0x04ULL);
    uint8_t  address_mode = ::read_byte(elf);
    if (address_mode != 1 && address_mode != 2)
    {
        elf.seekg(0x1CULL);
        uint32_t const  phd_offset_32 = ::read_bytes_to_uint32_t(elf,4U,is_file_in_big_endian);
        uint64_t const  phd_offset_64 = ::read_bytes_to_uint64_t(elf,8U,is_file_in_big_endian);
        bool const  cond32 = phd_offset_32 != 0U && phd_offset_32 < file_size(elf_file);
        bool const  cond64 = phd_offset_64 != 0U && phd_offset_64 < file_size(elf_file);
        if (cond32 && !cond64)
        {
            address_mode =  1U;
            LOAD_ELF_WARNING_IN(
                        elf_file,
                        "[Header offset 0x04] Unknown type for address mode (neither 32- nor 64-bit). "
                        "The 32-bit address mode was deduced form the 12 bytes at the offset 0x1c."
                        );
        }
        else if (!cond32 && cond64)
        {
            address_mode =  2U;
            LOAD_ELF_WARNING_IN(
                        elf_file,
                        "[Header offset 0x04] Unknown type for address mode (neither 32- nor 64-bit). "
                        "The 64-bit address mode was deduced form the 12 bytes at the offset 0x1c."
                        );
        }
        else
        {
            error_message = "[ELF][Header offset 0x04] Unknown type for address mode (neither 32- nor 64-bit).";
            return file_props_ptr();
        }
    }
    bool const file_uses_32_bit_addresses = address_mode == 1 ? true : false;

    elf.seekg(0x06ULL);

    file_props_ptr const  elf_props{ new file_props{
            normalise_path(absolute_path(elf_file)),
            format::ELF(),
            is_file_in_big_endian,
            (uint8_t)(file_uses_32_bit_addresses ? 32U : 64U),
            load_props.get_fresh_file_id()
            }};
    set_file_property(elf_props->property_map(), file_properties::abi_loader(), abi_loaders::NONE());

    return elf_props;
}
Пример #10
0
int ls(const char *path, ulong flags)
{
	DIR *dir;
	struct dirent *d;
	char tmp[PATH_MAX];
	struct stat s;
	struct string_list sl;

	string_list_init(&sl);

	if (stat(path, &s))
		return errno;

	if (flags & LS_SHOWARG && s.st_mode & S_IFDIR)
		printf("%s:\n", path);

	if (!(s.st_mode & S_IFDIR)) {
		ls_one(path, &s);
		return 0;
	}

	dir = opendir(path);
	if (!dir)
		return errno;

	while ((d = readdir(dir))) {
		sprintf(tmp, "%s/%s", path, d->d_name);
		if (stat(tmp, &s))
			goto out;
		if (flags & LS_COLUMN)
			string_list_add_sorted(&sl, d->d_name);
		else
			ls_one(d->d_name, &s);
	}

	closedir(dir);

	if (flags & LS_COLUMN) {
		string_list_print_by_column(&sl);
		string_list_free(&sl);
	}

	if (!(flags & LS_RECURSIVE))
		return 0;

	dir = opendir(path);
	if (!dir) {
		errno = -ENOENT;
		return -ENOENT;
	}

	while ((d = readdir(dir))) {

		if (!strcmp(d->d_name, "."))
			continue;
		if (!strcmp(d->d_name, ".."))
			continue;
		sprintf(tmp, "%s/%s", path, d->d_name);

		if (stat(tmp, &s))
			goto out;
		if (s.st_mode & S_IFDIR) {
			char *norm = normalise_path(tmp);
			ls(norm, flags);
			free(norm);
		}
	}
out:
	closedir(dir);

	return 0;
}