コード例 #1
0
ファイル: menus.c プロジェクト: lyuts/vifm
/* Extracts path and line number from the spec (1 when absent from the spec).
 * Returns path and sets *line_num to line number, otherwise NULL is
 * returned. */
TSTATIC char *
parse_spec(const char spec[], int *line_num)
{
	char *path_buf;
	const char *colon;
	int colon_lookup_offset = 0;
	const size_t bufs_len = 2 + strlen(spec) + 1 + 1;

	path_buf = malloc(bufs_len);
	if(path_buf == NULL)
	{
		return NULL;
	}

	if(is_path_absolute(spec))
	{
		path_buf[0] = '\0';
	}
	else
	{
		copy_str(path_buf, bufs_len, "./");
	}

#ifdef _WIN32
	if(is_path_absolute(spec))
	{
		colon_lookup_offset = 2;
	}
#endif

	colon = strchr(spec + colon_lookup_offset, ':');
	if(colon != NULL)
	{
		strncat(path_buf, spec, colon - spec);
		*line_num = atoi(colon + 1);
	}
	else
	{
		strcat(path_buf, spec);
		*line_num = 1;
	}

	chomp(path_buf);

#ifdef _WIN32
	to_forward_slash(path_buf);
#endif

	return path_buf;
}
コード例 #2
0
ファイル: config.c プロジェクト: phantasea/vifm
int
cfg_set_fuse_home(const char new_value[])
{
#ifdef _WIN32
	char with_forward_slashes[strlen(new_value) + 1];
	strcpy(with_forward_slashes, new_value);
	system_to_internal_slashes(with_forward_slashes);
	new_value = with_forward_slashes;
#endif

	char canonicalized[PATH_MAX + 1];
	canonicalize_path(new_value, canonicalized, sizeof(canonicalized));

	if(!is_path_absolute(new_value))
	{
		if(cfg.fuse_home == NULL)
		{
			/* Do not leave cfg.fuse_home uninitialized. */
			cfg.fuse_home = strdup("");
		}

		show_error_msgf("Error Setting FUSE Home Directory",
				"The path is not absolute: %s", canonicalized);
		return 1;
	}

	return replace_string(&cfg.fuse_home, canonicalized);
}
コード例 #3
0
ファイル: main.c プロジェクト: cybik/regal
static void set_absolute_path(char *options[], const char *option_name,
                              const char *path_to_civetweb_exe)
{
    char path[PATH_MAX] = "", abs[PATH_MAX] = "", *option_value;
    const char *p;

    /* Check whether option is already set */
    option_value = get_option(options, option_name);

    /* If option is already set and it is an absolute path,
       leave it as it is -- it's already absolute. */
    if (option_value != NULL && !is_path_absolute(option_value)) {
        /* Not absolute. Use the directory where civetweb executable lives
           be the relative directory for everything.
           Extract civetweb executable directory into path. */
        if ((p = strrchr(path_to_civetweb_exe, DIRSEP)) == NULL) {
            IGNORE_UNUSED_RESULT(getcwd(path, sizeof(path)));
        } else {
            snprintf(path, sizeof(path)-1, "%.*s", (int) (p - path_to_civetweb_exe),
                     path_to_civetweb_exe);
            path[sizeof(path)-1] = 0;
        }

        strncat(path, "/", sizeof(path) - 1);
        strncat(path, option_value, sizeof(path) - 1);

        /* Absolutize the path, and set the option */
        IGNORE_UNUSED_RESULT(abs_path(path, abs, sizeof(abs)));
        set_option(options, option_name, abs);
    }
}
コード例 #4
0
ファイル: vim.c プロジェクト: cosminadrianpopescu/vifm
/* Writes list of full paths to files into the file pointed to by fp.  files and
 * nfiles parameters can be used to supply list of file names in the current
 * directory of the view.  Otherwise current selection is used if current files
 * is selected, if current file is not selected it's the only one that is
 * stored. */
static void
dump_filenames(const FileView *view, FILE *fp, int nfiles, char *files[])
{
	/* Break delimiter in it's first character and the rest to be able to insert
	 * null character via "%c%s" format string. */
	const char delim_c = curr_stats.output_delimiter[0];
	const char *const delim_str = curr_stats.output_delimiter[0] == '\0'
	                            ? ""
	                            : curr_stats.output_delimiter + 1;

	if(nfiles == 0)
	{
		dir_entry_t *entry = NULL;
		while(iter_active_area((FileView *)view, &entry))
		{
			fprintf(fp, "%s/%s%c%s", entry->origin, entry->name, delim_c, delim_str);
		}
	}
	else
	{
		int i;
		for(i = 0; i < nfiles; ++i)
		{
			if(is_path_absolute(files[i]))
			{
				fprintf(fp, "%s%c%s", files[i], delim_c, delim_str);
			}
			else
			{
				fprintf(fp, "%s/%s%c%s", view->curr_dir, files[i], delim_c, delim_str);
			}
		}
	}
}
コード例 #5
0
ファイル: config.c プロジェクト: phantasea/vifm
/* Tries to use $XDG_CONFIG_HOME/vifm as configuration directory.  Returns
 * non-zero on success, otherwise zero is returned. */
static int
try_xdg_for_conf(void)
{
	LOG_FUNC_ENTER;

	char *config_dir;

	const char *const config_home = env_get("XDG_CONFIG_HOME");
	if(!is_null_or_empty(config_home) && is_path_absolute(config_home))
	{
		config_dir = format_str("%s/vifm", config_home);
	}
	else if(path_exists_at(env_get(HOME_EV), ".config", DEREF))
	{
		config_dir = format_str("%s/.config/vifm", env_get(HOME_EV));
	}
	else
	{
		return 0;
	}

	env_set(VIFM_EV, config_dir);
	free(config_dir);

	return 1;
}
コード例 #6
0
ファイル: args.c プロジェクト: cosminadrianpopescu/vifm
/* Checks whether argument mentions a valid path.  Returns non-zero if so,
 * otherwise zero is returned. */
static int
is_path_arg(const char arg[])
{
	/* FIXME: why allow inexistent absolute paths? */
	return path_exists(arg, DEREF) || is_path_absolute(arg) || is_root_dir(arg)
		  || strcmp(arg, "-") == 0;
}
コード例 #7
0
ファイル: server.c プロジェクト: Frankie-666/flashdevelop
static void set_absolute_path(char *options[], const char *option_name) {
  char path[PATH_MAX], abs[PATH_MAX], *option_value;
  const char *p;

  // Check whether option is already set
  option_value = get_option(options, option_name);

  // If option is already set and it is an absolute path,
  // leave it as it is -- it's already absolute.
  if (option_value != NULL && !is_path_absolute(option_value)) {
    // Not absolute. Use the directory where mongoose executable lives
    // be the relative directory for everything.
    // Extract mongoose executable directory into path.
    if ((p = strrchr(s_config_file, DIRSEP)) == NULL) {
      getcwd(path, sizeof(path));
    } else {
      snprintf(path, sizeof(path), "%.*s", (int) (p - s_config_file),
               s_config_file);
    }

    strncat(path, "/", sizeof(path) - 1);
    strncat(path, option_value, sizeof(path) - 1);

    // Absolutize the path, and set the option
    abs_path(path, abs, sizeof(abs));
    set_option(options, option_name, abs);
  }
}
コード例 #8
0
ファイル: vifm.c プロジェクト: ackeack/workenv
/* buf should be at least PATH_MAX characters length */
static void
parse_path(const char *dir, const char *path, char *buf)
{
	strcpy(buf, path);
#ifdef _WIN32
	to_forward_slash(buf);
#endif
	if(is_path_absolute(buf))
	{
		snprintf(buf, PATH_MAX, "%s", path);
	}
#ifdef _WIN32
	else if(buf[0] == '/')
	{
		snprintf(buf, PATH_MAX, "%c:%s", dir[0], path);
	}
#endif
	else
	{
		char new_path[PATH_MAX];
		snprintf(new_path, sizeof(new_path), "%s/%s", dir, path);
		canonicalize_path(new_path, buf, PATH_MAX);
	}
	if(!is_root_dir(buf))
		chosp(buf);

#ifdef _WIN32
	to_forward_slash(buf);
#endif
}
コード例 #9
0
ファイル: path.c プロジェクト: jubalh/vifm
int
to_canonic_path(const char path[], char buf[], size_t buf_len)
{
	if(!is_path_absolute(path))
	{
		char cwd[PATH_MAX];
		char full_path[PATH_MAX];

		if(getcwd(cwd, sizeof(cwd)) == NULL)
		{
			/* getcwd() failed, we can't use relative path, so fail. */
			LOG_SERROR_MSG(errno, "Can't get CWD");
			return 1;
		}

		snprintf(full_path, sizeof(full_path), "%s/%s", cwd, path);
		canonicalize_path(full_path, buf, buf_len);
	}
	else
	{
		canonicalize_path(path, buf, buf_len);
	}

	chosp(buf);
	return 0;
}
コード例 #10
0
int
path_exists_at(const char path[], const char filename[], int deref)
{
	if(is_path_absolute(filename))
	{
		LOG_ERROR_MSG("Passed absolute path where relative one is expected: %s",
				filename);
	}
	return path_exists_internal(path, filename, deref);
}
コード例 #11
0
ファイル: fs.c プロジェクト: cfillion/vifm
int
path_exists(const char path[], int deref)
{
	if(!is_path_absolute(path))
	{
		LOG_ERROR_MSG("Passed relative path where absolute one is expected: %s",
				path);
	}
	return path_exists_internal(NULL, path, deref);
}
コード例 #12
0
ファイル: commands_completion.c プロジェクト: sshilovsky/vifm
char *
fast_run_complete(const char cmd[])
{
	char *result = NULL;
	const char *args;
	char command[NAME_MAX];
	char *completed;

	args = extract_cmd_name(cmd, 0, sizeof(command), command);

	if(is_path_absolute(command))
	{
		return strdup(cmd);
	}

	vle_compl_reset();
	complete_command_name(command);
	vle_compl_unite_groups();
	completed = vle_compl_next();

	if(vle_compl_get_count() > 2)
	{
		int c = vle_compl_get_count() - 1;
		while(c-- > 0)
		{
			if(stroscmp(command, completed) == 0)
			{
				result = strdup(cmd);
				break;
			}
			else
			{
				free(completed);
				completed = vle_compl_next();
			}
		}

		if(result == NULL)
		{
			status_bar_error("Command beginning is ambiguous");
		}
	}
	else
	{
		free(completed);
		completed = vle_compl_next();
		result = format_str("%s %s", completed, args);
	}
	free(completed);

	return result;
}
コード例 #13
0
ファイル: flist_custom.c プロジェクト: richarddewit/vifm
SETUP_ONCE()
{
	char cwd[PATH_MAX];
	assert_non_null(get_cwd(cwd, sizeof(cwd)));

	if(is_path_absolute(TEST_DATA_PATH))
	{
		snprintf(test_data, sizeof(test_data), "%s", TEST_DATA_PATH);
	}
	else
	{
		snprintf(test_data, sizeof(test_data), "%s/%s", cwd, TEST_DATA_PATH);
	}
}
コード例 #14
0
ファイル: utils.c プロジェクト: acklinr/vifm
void
set_to_sandbox_path(char buf[], size_t buf_len)
{
	if(is_path_absolute(SANDBOX_PATH))
	{
		strcpy(buf, SANDBOX_PATH);
	}
	else
	{
		char cwd[PATH_MAX + 1];
		assert_non_null(get_cwd(cwd, sizeof(cwd)));
		snprintf(buf, buf_len, "%s/%s", cwd, SANDBOX_PATH);
	}
}
コード例 #15
0
ファイル: info.c プロジェクト: cfillion/vifm
/* Performs conversions on files in trash required for partial backward
 * compatibility.  Returns newly allocated string that should be freed by the
 * caller. */
static char *
convert_old_trash_path(const char trash_path[])
{
	if(!is_path_absolute(trash_path) && is_dir_writable(cfg.trash_dir))
	{
		char *const full_path = format_str("%s/%s", cfg.trash_dir, trash_path);
		if(path_exists(full_path, DEREF))
		{
			return full_path;
		}
		free(full_path);
	}
	return strdup(trash_path);
}
コード例 #16
0
std::string normalise_path(const std::string& path)
{
	if(is_path_absolute(path)) { 
		return path;
	}
	std::vector<std::string> cur_path;
	std::string norm_path;
	boost::split(cur_path, path, boost::is_any_of("/"));
	foreach(const std::string& s, cur_path) {
		if(s != ".") {
			norm_path += s + "/";
		}
	}
	return norm_path;
}
コード例 #17
0
ファイル: filesystem.cpp プロジェクト: sweetkristas/wte
std::string normalise_path(const std::string& path)
{
	if(is_path_absolute(path)) { 
		return path;
	}
	std::vector<std::string> cur_path;
	std::string norm_path;
	boost::split(cur_path, path, std::bind2nd(std::equal_to<char>(), '/'));
	foreach(const std::string& s, cur_path) {
		if(s != ".") {
			norm_path += s + "/";
		}
	}
	return norm_path;
}
コード例 #18
0
ファイル: filename_modifiers.c プロジェクト: cfillion/vifm
/* Implementation of :p filename modifier. */
static int
apply_p_mod(const char *path, const char *parent, char *buf, size_t buf_len)
{
	size_t len;
	if(is_path_absolute(path))
	{
		snprintf(buf, buf_len, "%s", path);
		return 0;
	}

	snprintf(buf, buf_len, "%s", parent);
	chosp(buf);
	len = strlen(buf);
	snprintf(buf + len, buf_len - len, "/%s", path);
	return 0;
}
コード例 #19
0
ファイル: config.c プロジェクト: ackeack/workenv
int
set_trash_dir(const char new_value[])
{
	if(!is_path_absolute(new_value))
	{
		show_error_msgf("Error Setting Trash Directory",
				"The path is not absolute: %s", new_value);
		return 1;
	}
	if(create_trash_dir(new_value) != 0)
	{
		return 1;
	}
	snprintf(cfg.trash_dir, sizeof(cfg.trash_dir), "%s", new_value);
	return 0;
}
コード例 #20
0
ファイル: config.c プロジェクト: phantasea/vifm
/* Tries to find directory for data files. */
static void
find_data_dir(void)
{
	LOG_FUNC_ENTER;

	const char *const data_home = env_get("XDG_DATA_HOME");
	if(is_null_or_empty(data_home) || !is_path_absolute(data_home))
	{
		snprintf(cfg.data_dir, sizeof(cfg.data_dir) - 4, "%s/.local/share/",
				env_get(HOME_EV));
	}
	else
	{
		snprintf(cfg.data_dir, sizeof(cfg.data_dir) - 4, "%s/", data_home);
	}

	strcat(cfg.data_dir, "vifm");
}
コード例 #21
0
ファイル: trash.c プロジェクト: cosminadrianpopescu/vifm
/* Validates trash directory specification.  Returns non-zero if it's OK,
 * otherwise zero is returned and an error message is displayed. */
static int
validate_spec(const char spec[])
{
	if(is_path_absolute(spec))
	{
		if(create_trash_dir(spec) != 0)
		{
			return 0;
		}
	}
	else if(!is_rooted_trash_dir(spec))
	{
		show_error_msgf("Error Setting Trash Directory",
				"The path specification is of incorrect format: %s", spec);
		return 0;
	}
	return 1;
}
コード例 #22
0
ファイル: fs.c プロジェクト: cfillion/vifm
int
get_link_target_abs(const char link[], const char cwd[], char buf[],
		size_t buf_len)
{
	char link_target[PATH_MAX];
	if(get_link_target(link, link_target, sizeof(link_target)) != 0)
	{
		return 1;
	}
	if(is_path_absolute(link_target))
	{
		strncpy(buf, link_target, buf_len);
		buf[buf_len - 1] = '\0';
	}
	else
	{
		snprintf(buf, buf_len, "%s/%s", cwd, link_target);
	}
	return 0;
}
コード例 #23
0
SETUP()
{
#ifndef _WIN32
	update_string(&cfg.shell, "/bin/sh");
#else
	update_string(&cfg.shell, "cmd");
#endif

	update_string(&cfg.vi_command, "echo");

	stats_update_shell_type(cfg.shell);

	lwin.list_rows = 2;
	lwin.list_pos = 0;
	lwin.dir_entry = dynarray_cextend(NULL,
			lwin.list_rows*sizeof(*lwin.dir_entry));
	lwin.dir_entry[0].name = strdup("a");
	lwin.dir_entry[0].origin = &lwin.curr_dir[0];
	lwin.dir_entry[0].selected = 1;
	lwin.dir_entry[1].name = strdup("b");
	lwin.dir_entry[1].origin = &lwin.curr_dir[0];
	lwin.dir_entry[1].selected = 1;
	lwin.selected_files = 2;
	curr_view = &lwin;

	ft_init(&prog_exists);

	if(is_path_absolute(TEST_DATA_PATH))
	{
		snprintf(lwin.curr_dir, sizeof(lwin.curr_dir), "%s/existing-files",
				TEST_DATA_PATH);
	}
	else
	{
		char cwd[PATH_MAX];
		assert_non_null(get_cwd(cwd, sizeof(cwd)));

		snprintf(lwin.curr_dir, sizeof(lwin.curr_dir), "%s/%s/existing-files", cwd,
				TEST_DATA_PATH);
	}
}
コード例 #24
0
ファイル: config.c プロジェクト: ackeack/workenv
int
set_fuse_home(const char new_value[])
{
	char canonicalized[PATH_MAX];
#ifdef _WIN32
	char with_forward_slashes[strlen(new_value) + 1];
	strcpy(with_forward_slashes, new_value);
	to_forward_slash(with_forward_slashes);
	new_value = with_forward_slashes;
#endif
	canonicalize_path(new_value, canonicalized, sizeof(canonicalized));

	if(!is_path_absolute(new_value))
	{
		show_error_msgf("Error Setting FUSE Home Directory",
				"The path is not absolute: %s", canonicalized);
		return 1;
	}

	return replace_string(&cfg.fuse_home, canonicalized);
}
コード例 #25
0
ファイル: builtin_functions.c プロジェクト: sshilovsky/vifm
/* Checks whether executable exists at absolute path orin directories listed in
 * $PATH when path isn't absolute.  Checks for various executable extensions on
 * Windows.  Returns boolean value describing result of the check. */
static var_t
executable_builtin(const call_info_t *call_info)
{
	int exists;
	char *str_val;

	str_val = var_to_string(call_info->argv[0]);

	if(is_path_absolute(str_val))
	{
		exists = executable_exists(str_val);
	}
	else
	{
		exists = (find_cmd_in_path(str_val, 0UL, NULL) == 0);
	}

	free(str_val);

	return exists ? var_true() : var_false();
}
コード例 #26
0
ファイル: package.c プロジェクト: dleonard0/ponyc
// Attempt to find the specified package directory in our search path
// @return The resulting directory path, which should not be deleted and is
// valid indefinitely. NULL is directory cannot be found.
static const char* find_path(ast_t* from, const char* path)
{
  // First check for an absolute path
  if(is_path_absolute(path))
    return try_path(NULL, path);

  const char* result;

  if((from == NULL) || (ast_id(from) == TK_PROGRAM))
  {
    // Try a path relative to the current working directory
    result = try_path(NULL, path);

    if(result != NULL)
      return result;
  }
  else
  {
    // Try a path relative to the importing package
    from = ast_nearest(from, TK_PACKAGE);
    package_t* pkg = (package_t*)ast_data(from);
    result = try_path(pkg->path, path);

    if(result != NULL)
      return result;
  }

  // Try the search paths
  for(strlist_t* p = search; p != NULL; p = strlist_next(p))
  {
    result = try_path(strlist_data(p), path);

    if(result != NULL)
      return result;
  }

  errorf(path, "couldn't locate this path");
  return NULL;
}
コード例 #27
0
ファイル: utils.c プロジェクト: acklinr/vifm
void
make_abs_path(char buf[], size_t buf_len, const char base[], const char sub[],
		const char cwd[])
{
	char local_buf[buf_len];

	if(is_path_absolute(base))
	{
		snprintf(local_buf, buf_len, "%s%s%s", base, (sub[0] == '\0' ? "" : "/"),
				sub);
	}
	else
	{
		snprintf(local_buf, buf_len, "%s/%s%s%s", cwd, base,
				(sub[0] == '\0' ? "" : "/"), sub);
	}

	canonicalize_path(local_buf, buf, buf_len);
	if(!ends_with_slash(sub) && !is_root_dir(buf))
	{
		chosp(buf);
	}
}
コード例 #28
0
ファイル: program.c プロジェクト: Preetam/ponyc
void program_lib_build_args(ast_t* program, const char* path_preamble,
  const char* global_preamble, const char* global_postamble,
  const char* lib_premable, const char* lib_postamble)
{
  assert(program != NULL);
  assert(ast_id(program) == TK_PROGRAM);
  assert(global_preamble != NULL);
  assert(global_postamble != NULL);
  assert(lib_premable != NULL);
  assert(lib_postamble != NULL);

  program_t* data = (program_t*)ast_data(program);
  assert(data != NULL);
  assert(data->lib_args == NULL); // Not yet built args

  // Start with an arbitrary amount of space
  data->lib_args_alloced = 256;
  data->lib_args = (char*)malloc(data->lib_args_alloced);
  data->lib_args[0] = '\0';
  data->lib_args_size = 0;

  // Library paths defined in the source code.
  for(strlist_t* p = data->libpaths; p != NULL; p = strlist_next(p))
  {
    const char* libpath = strlist_data(p);
    append_to_args(data, path_preamble);
    append_to_args(data, libpath);
    append_to_args(data, " ");
  }

  // Library paths from the command line and environment variable.
  for(strlist_t* p = package_paths(); p != NULL; p = strlist_next(p))
  {
    const char* libpath = quoted_locator(NULL, strlist_data(p));

    if(libpath == NULL)
      continue;

    append_to_args(data, path_preamble);
    append_to_args(data, libpath);
    append_to_args(data, " ");
  }

  // Library names.
  append_to_args(data, global_preamble);

  for(strlist_t* p = data->libs; p != NULL; p = strlist_next(p))
  {
    const char* lib = strlist_data(p);
    bool amble = !is_path_absolute(lib);

    if(amble)
      append_to_args(data, lib_premable);

    append_to_args(data, lib);

    if(amble)
      append_to_args(data, lib_postamble);

    append_to_args(data, " ");
  }

  append_to_args(data, global_postamble);
}
コード例 #29
0
ファイル: package.c プロジェクト: lzpfmh/ponyc
// Attempt to find the specified package directory in our search path
// @return The resulting directory path, which should not be deleted and is
// valid indefinitely. NULL is directory cannot be found.
static const char* find_path(ast_t* from, const char* path,
  bool* out_is_relative)
{
  if(out_is_relative != NULL)
    *out_is_relative = false;

  // First check for an absolute path
  if(is_path_absolute(path))
    return try_path(NULL, path);

  // Get the base directory
  const char* base;

  if((from == NULL) || (ast_id(from) == TK_PROGRAM))
  {
    base = NULL;
  } else {
    from = ast_nearest(from, TK_PACKAGE);
    package_t* pkg = (package_t*)ast_data(from);
    base = pkg->path;
  }

  // Try a path relative to the base
  const char* result = try_path(base, path);

  if(result != NULL)
  {
    if(out_is_relative != NULL)
      *out_is_relative = true;

    return result;
  }

  // If it's a relative path, don't try elsewhere
  if(!is_path_relative(path))
  {
    // Check ../pony_packages and further up the tree
    if(base != NULL)
    {
      result = try_package_path(base, path);

      if(result != NULL)
        return result;

      // Check ../pony_packages from the compiler target
      if((from != NULL) && (ast_id(from) == TK_PACKAGE))
      {
        ast_t* target = ast_child(ast_parent(from));
        package_t* pkg = (package_t*)ast_data(target);
        base = pkg->path;

        result = try_package_path(base, path);

        if(result != NULL)
          return result;
      }
    }

    // Try the search paths
    for(strlist_t* p = search; p != NULL; p = strlist_next(p))
    {
      result = try_path(strlist_data(p), path);

      if(result != NULL)
        return result;
    }
  }

  errorf(path, "couldn't locate this path");
  return NULL;
}
コード例 #30
0
ファイル: commands_completion.c プロジェクト: sshilovsky/vifm
/*
 * type: CT_*
 */
void
filename_completion(const char *str, CompletionType type)
{
	/* TODO refactor filename_completion(...) function */
	DIR * dir;
	char * dirname;
	char * filename;
	char * temp;

	if(str[0] == '~' && strchr(str, '/') == NULL)
	{
		char *const tilde_expanded = expand_tilde(str);
		vle_compl_add_path_match(tilde_expanded);
		free(tilde_expanded);
		return;
	}

	dirname = expand_tilde(str);
	filename = strdup(dirname);

	temp = cmds_expand_envvars(dirname);
	free(dirname);
	dirname = temp;

	temp = strrchr(dirname, '/');
	if(temp != NULL && type != CT_FILE && type != CT_FILE_WOE)
	{
		strcpy(filename, ++temp);
		*temp = '\0';
	}
	else
	{
		dirname = realloc(dirname, 2);
		strcpy(dirname, ".");
	}

#ifdef _WIN32
	if(is_unc_root(dirname) ||
			(stroscmp(dirname, ".") == 0 && is_unc_root(curr_view->curr_dir)) ||
			(stroscmp(dirname, "/") == 0 && is_unc_path(curr_view->curr_dir)))
	{
		char buf[PATH_MAX];
		if(!is_unc_root(dirname))
			snprintf(buf,
					strchr(curr_view->curr_dir + 2, '/') - curr_view->curr_dir + 1, "%s",
					curr_view->curr_dir);
		else
			snprintf(buf, sizeof(buf), "%s", dirname);

		complete_with_shared(buf, filename);
		free(filename);
		free(dirname);
		return;
	}
	if(is_unc_path(curr_view->curr_dir))
	{
		char buf[PATH_MAX];
		if(is_path_absolute(dirname) && !is_unc_root(curr_view->curr_dir))
			snprintf(buf,
					strchr(curr_view->curr_dir + 2, '/') - curr_view->curr_dir + 2, "%s",
					curr_view->curr_dir);
		else
			snprintf(buf, sizeof(buf), "%s", curr_view->curr_dir);
		strcat(buf, dirname);
		chosp(buf);
		(void)replace_string(&dirname, buf);
	}
#endif

	dir = opendir(dirname);

	if(dir == NULL || vifm_chdir(dirname) != 0)
	{
		vle_compl_add_path_match(filename);
	}
	else
	{
		filename_completion_internal(dir, dirname, filename, type);
		(void)vifm_chdir(curr_view->curr_dir);
	}

	free(filename);
	free(dirname);

	if(dir != NULL)
	{
		closedir(dir);
	}
}