Ejemplo n.º 1
0
/* Resolve link target and either navigate inside directory link points to or
 * navigate to directory where target is located pointing cursor on
 * it (the follow_dirs flag controls behaviour). */
static void
follow_link(FileView *view, int follow_dirs)
{
	char *dir, *file;
	char full_path[PATH_MAX];
	char linkto[PATH_MAX + NAME_MAX];
	dir_entry_t *const entry = &curr_view->dir_entry[curr_view->list_pos];

	get_full_path_of(entry, sizeof(full_path), full_path);

	if(get_link_target_abs(full_path, entry->origin, linkto, sizeof(linkto)) != 0)
	{
		show_error_msg("Error", "Can't read link.");
		return;
	}

	if(!path_exists(linkto, DEREF))
	{
		show_error_msg("Broken Link",
				"Can't access link destination.  It might be broken.");
		return;
	}

	chosp(linkto);

	if(is_dir(linkto) && !follow_dirs)
	{
		dir = strdup(entry->name);
		file = NULL;
	}
	else
	{
		dir = strdup(linkto);
		remove_last_path_component(dir);

		file = get_last_path_component(linkto);
	}

	if(dir[0] != '\0')
	{
		navigate_to(view, dir);
	}

	if(file != NULL)
	{
		const int pos = find_file_pos_in_list(view, file);
		if(pos >= 0)
		{
			flist_set_pos(view, pos);
		}
	}

	free(dir);
}
Ejemplo n.º 2
0
/* Checks whether path matches pattern in the autocommand.  Returns non-zero if
 * so, otherwise zero is returned. */
static int
is_pattern_match(const aucmd_info_t *autocmd, const char path[])
{
	const char *const part = (strchr(autocmd->pattern, '/') == NULL)
	                       ? get_last_path_component(path)
	                       : path;

	/* Leading start shouldn't match dot at the first character.  Can't be
	 * handled by globs->regex translation. */
	if(autocmd->pattern[0] == '*' && part[0] == '.')
	{
		return 0;
	}

	return (regexec(&autocmd->regex, part, 0, NULL, 0) == 0)^autocmd->negated;
}
Ejemplo n.º 3
0
TEST(chase_links_causes_link_to_be_resolved, IF(not_windows))
{
	assert_success(os_mkdir("dir", 0700));

	/* symlink() is not available on Windows, but other code is fine. */
#ifndef _WIN32
	assert_success(symlink("dir", "dir-link"));
#endif

	assert_non_null(get_cwd(curr_view->curr_dir, sizeof(curr_view->curr_dir)));
	assert_true(change_directory(curr_view, "dir-link") >= 0);
	assert_string_equal("dir", get_last_path_component(curr_view->curr_dir));

	/* Go out of the directory so that we can remove it. */
	assert_true(change_directory(curr_view, "..") >= 0);

	assert_success(rmdir("dir"));
	assert_success(remove("dir-link"));
}
extern int basename_main(int argc, char **argv)
{
	int m, n;
	char *s;

	if ((argc < 2) || (**(argv + 1) == '-')) {
		show_usage();
	}

	argv++;

	s = get_last_path_component(*argv);

	if (argc>2) {
		argv++;
		n = strlen(*argv);
		m = strlen(s);
		if (m>=n && strncmp(s+m-n, *argv, n)==0)
			s[m-n] = '\0';
	}
	printf("%s\n", s);
	return EXIT_SUCCESS;
}
Ejemplo n.º 5
0
Archivo: view.c Proyecto: lyuts/vifm
/* Reads data to be displayed handling error cases.  Returns zero on success, 1
 * if file is a directory, 2 on file reading error, 3 on issues with viewer or
 * 4 on empty input. */
static int
get_view_data(view_info_t *vi, const char file_to_view[])
{
	FILE *fp;

	const char *const viewer =
		get_viewer_for_file(get_last_path_component(file_to_view));

	if(is_null_or_empty(viewer))
	{
		if(is_dir(file_to_view))
		{
			return 1;
		}
		else if((fp = fopen(file_to_view, "rb")) == NULL)
		{
			return 2;
		}
	}
	else if((fp = use_info_prog(viewer)) == NULL)
	{
		return 3;
	}

	vi->lines = is_null_or_empty(viewer)
		? read_file_lines(fp, &vi->nlines)
		: read_stream_lines(fp, &vi->nlines);

	fclose(fp);

	if(vi->lines == NULL || vi->nlines == 0)
	{
		return 4;
	}

	return 0;
}
Ejemplo n.º 6
0
/* Extracts last part of the path into buf.  Assumes that size of the buf is
 * large enough. */
static void
extract_last_path_component(const char path[], char buf[])
{
	const char *const last = get_last_path_component(path);
	snprintf(buf, until_first(last, '/') - last + 1, "%s", last);
}
Ejemplo n.º 7
0
extern int grep_main(int argc, char **argv)
{
	int opt;
#if defined BB_FEATURE_GREP_CONTEXT || defined BB_FEATURE_GREP_EGREP_ALIAS
	char *junk;
#endif

#ifdef BB_FEATURE_CLEAN_UP
	/* destroy command strings on exit */
	atexit(destroy_regexes);
#endif

#ifdef BB_FEATURE_GREP_EGREP_ALIAS
	junk = get_last_path_component(argv[0]);
	if (junk && strcmp(junk, "egrep") == 0)
		reflags |= REG_EXTENDED;
#endif

	/* do normal option parsing */
	while ((opt = getopt(argc, argv, "iHhlnqvsce:f:"
#ifdef BB_FEATURE_GREP_CONTEXT
"A:B:C:"
#endif
#ifdef BB_FEATURE_GREP_EGREP_ALIAS
"E"
#endif
)) > 0) {
		switch (opt) {
			case 'i':
				ignore_case++;
				break;
			case 'l':
				print_files_with_matches++;
				break;
			case 'H':
				print_filename++;
				break;
			case 'h':
				print_filename--;
				break;
			case 'n':
				print_line_num++;
				break;
			case 'q':
				be_quiet++;
				break;
			case 'v':
				invert_search++;
				break;
			case 's':
				suppress_err_msgs++;
				break;
			case 'c':
				print_match_counts++;
				break;
			case 'e':
				add_regex(optarg);
				break;
#ifdef BB_FEATURE_GREP_EGREP_ALIAS
			case 'E':
				reflags |= REG_EXTENDED;
				break;
#endif
			case 'f':
				load_regexes_from_file(optarg);
				break;
#ifdef BB_FEATURE_GREP_CONTEXT
			case 'A':
				lines_after = strtoul(optarg, &junk, 10);
				if(*junk != '\0')
					error_msg_and_die("invalid context length argument");
				break;
			case 'B':
				lines_before = strtoul(optarg, &junk, 10);
				if(*junk != '\0')
					error_msg_and_die("invalid context length argument");
				before_buf = (char **)xcalloc(lines_before, sizeof(char *));
				break;
			case 'C':
				lines_after = lines_before = strtoul(optarg, &junk, 10);
				if(*junk != '\0')
					error_msg_and_die("invalid context length argument");
				before_buf = (char **)xcalloc(lines_before, sizeof(char *));
				break;
#endif /* BB_FEATURE_GREP_CONTEXT */
			default:
				show_usage();
		}
	}

	/* if we didn't get a pattern from a -e and no command file was specified,
	 * argv[optind] should be the pattern. no pattern, no worky */
	if (nregexes == 0) {
		if (argv[optind] == NULL)
			show_usage();
		else {
			add_regex(argv[optind]);
			optind++;
		}
	}

	/* sanity checks */
	if (print_match_counts || be_quiet || print_files_with_matches) {
		print_line_num = 0;
#ifdef BB_FEATURE_GREP_CONTEXT
		lines_before = 0;
		lines_after = 0;
#endif
	}

	/* argv[(optind)..(argc-1)] should be names of file to grep through. If
	 * there is more than one file to grep, we will print the filenames */
	if ((argc-1) - (optind) > 0)
		print_filename++;

	/* If no files were specified, or '-' was specified, take input from
	 * stdin. Otherwise, we grep through all the files specified. */
	if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
		grep_file(stdin);
	}
	else {
		int i;
		FILE *file;
		for (i = optind; i < argc; i++) {
			cur_file = argv[i];
			file = fopen(cur_file, "r");
			if (file == NULL) {
				if (!suppress_err_msgs)
					perror_msg("%s", cur_file);
			}
			else {
				grep_file(file);
				fclose(file);
			}
		}
	}

	return !matched; /* invert return value 0 = success, 1 = failed */
}
Ejemplo n.º 8
0
static fssh_status_t
command_ln(int argc, const char* const* argv)
{
	bool force = false;
	bool symbolic = false;
	bool dereference = true;

	// parse parameters
	int argi = 1;
	for (argi = 1; argi < argc; argi++) {
		const char *arg = argv[argi];
		if (arg[0] != '-')
			break;

		if (arg[1] == '\0') {
			fprintf(stderr, "Error: Invalid option \"-\"\n");
			return FSSH_B_BAD_VALUE;
		}

		for (int i = 1; arg[i]; i++) {
			switch (arg[i]) {
				case 'f':
					force = true;
					break;
				case 's':
					symbolic = true;
					break;
				case 'n':
					dereference = false;
					break;
				default:
					fprintf(stderr, "Error: Unknown option \"-%c\"\n", arg[i]);
					return FSSH_B_BAD_VALUE;
			}
		}
	}

	if (argc - argi != 2) {
		fprintf(stderr, "Usage: %s [Options] <source> <target>\n", argv[0]);
		return FSSH_B_BAD_VALUE;
	}

	const char *source = argv[argi];
	const char *target = argv[argi + 1];

	// check, if the the target is an existing directory
	struct fssh_stat st;
	char targetBuffer[FSSH_B_PATH_NAME_LENGTH];
	fssh_status_t error = _kern_read_stat(-1, target, dereference, &st,
		sizeof(st));
	if (error == FSSH_B_OK) {
		if (FSSH_S_ISDIR(st.fssh_st_mode)) {
			// get source leaf
			char leaf[FSSH_B_FILE_NAME_LENGTH];
			error = get_last_path_component(source, leaf, sizeof(leaf));
			if (error != FSSH_B_OK) {
				fprintf(stderr, "Error: Failed to get leaf name of source "
					"path: %s\n", fssh_strerror(error));
				return error;
			}

			// compose a new path
			int len = strlen(target) + 1 + strlen(leaf);
			if (len > (int)sizeof(targetBuffer)) {
				fprintf(stderr, "Error: Resulting target path is too long.\n");
				return FSSH_B_BAD_VALUE;
			}

			strcpy(targetBuffer, target);
			strcat(targetBuffer, "/");
			strcat(targetBuffer, leaf);
			target = targetBuffer;
		}
	}

	// check, if the target exists
	error = _kern_read_stat(-1, target, false, &st, sizeof(st));
	if (error == FSSH_B_OK) {
		if (!force) {
			fprintf(stderr, "Error: Can't create link. \"%s\" is in the way.\n",
				target);
			return FSSH_B_FILE_EXISTS;
		}

		// unlink the entry
		error = _kern_unlink(-1, target);
		if (error != FSSH_B_OK) {
			fprintf(stderr, "Error: Failed to remove \"%s\" to make way for "
				"link: %s\n", target, fssh_strerror(error));
			return error;
		}
	}

	// finally create the link
	if (symbolic) {
		error = _kern_create_symlink(-1, target, source,
			FSSH_S_IRWXU | FSSH_S_IRWXG | FSSH_S_IRWXO);
	} else
		error = _kern_create_link(target, source);

	if (error != FSSH_B_OK) {
		fprintf(stderr, "Error: Failed to create link: %s\n",
			fssh_strerror(error));
	}

	return error;
}
Ejemplo n.º 9
0
Archivo: cp.c Proyecto: jvesely/helenos
static int64_t do_copy(const char *src, const char *dest,
    size_t blen, int vb, int recursive, int force, int interactive)
{
	int r = -1;
	char dest_path[PATH_MAX];
	char src_path[PATH_MAX];
	DIR *dir = NULL;
	struct dirent *dp;

	dentry_type_t src_type = get_type(src);
	dentry_type_t dest_type = get_type(dest);

	const size_t src_len = str_size(src);

	if (src_type == TYPE_FILE) {
		char *src_fname;

		/* Initialize the src_path with the src argument */
		str_cpy(src_path, src_len + 1, src);
		str_rtrim(src_path, '/');
		
		/* Get the last component name from the src path */
		src_fname = get_last_path_component(src_path);
		
		/* Initialize dest_path with the dest argument */
		str_cpy(dest_path, PATH_MAX, dest);

		if (dest_type == TYPE_DIR) {
			/* e.g. cp file_name /data */
			/* e.g. cp file_name /data/ */
			
			/* dest is a directory,
			 * append the src filename to it.
			 */
			merge_paths(dest_path, PATH_MAX, src_fname);
			dest_type = get_type(dest_path);
		} else if (dest_type == TYPE_NONE) {
			if (dest_path[str_size(dest_path) - 1] == '/') {
				/* e.g. cp /textdemo /data/dirnotexists/ */

				printf("The dest directory %s does not exists",
				    dest_path);
				goto exit;
			}
		}

		if (dest_type == TYPE_DIR) {
			printf("Cannot overwrite existing directory %s\n",
			    dest_path);
			goto exit;
		} else if (dest_type == TYPE_FILE) {
			/* e.g. cp file_name existing_file */

			/* dest already exists, 
			 * if force is set we will try to remove it.
			 * if interactive is set user input is required.
			 */
			if (force && !interactive) {
				if (unlink(dest_path) != 0) {
					printf("Unable to remove %s\n",
					    dest_path);
					goto exit;
				}
			} else if (!force && interactive) {
				bool overwrite = get_user_decision(false,
				    "File already exists: %s. Overwrite? [y/N]: ",
				    dest_path);
				if (overwrite) {
					printf("Overwriting file: %s\n", dest_path);
					if (unlink(dest_path) != 0) {
						printf("Unable to remove %s\n", dest_path);
						goto exit;
					}
				} else {
					printf("Not overwriting file: %s\n", dest_path);
					r = 0;
					goto exit;
				}
			} else {
				printf("File already exists: %s\n", dest_path);
				goto exit;
			}
		}

		/* call copy_file and exit */
		r = (copy_file(src, dest_path, blen, vb) < 0);

	} else if (src_type == TYPE_DIR) {
		/* e.g. cp -r /x/srcdir /y/destdir/ */

		if (!recursive) {
			printf("Cannot copy the %s directory without the "
			    "-r option\n", src);
			goto exit;
		} else if (dest_type == TYPE_FILE) {
			printf("Cannot overwrite a file with a directory\n");
			goto exit;
		}

		char *src_dirname;

		/* Initialize src_path with the content of src */
		str_cpy(src_path, src_len + 1, src);
		str_rtrim(src_path, '/');

		src_dirname = get_last_path_component(src_path);

		str_cpy(dest_path, PATH_MAX, dest);

		switch (dest_type) {
		case TYPE_DIR:
			if (str_cmp(src_dirname, "..") &&
			    str_cmp(src_dirname, ".")) {
				/* The last component of src_path is
				 * not '.' or '..'
				 */
				merge_paths(dest_path, PATH_MAX, src_dirname);

				if (mkdir(dest_path, 0) != 0) {
					printf("Unable to create "
					    "dest directory %s\n", dest_path);
					goto exit;
				}
			}
			break;
		default:
		case TYPE_NONE:
			/* dest does not exists, this means the user wants
			 * to specify the name of the destination directory
			 *
			 * e.g. cp -r /src /data/new_dir_src
			 */
			if (mkdir(dest_path, 0) != 0) {
				printf("Unable to create "
				    "dest directory %s\n", dest_path);
				goto exit;
			}
			break;
		}

		dir = opendir(src);
		if (!dir) {
			/* Something strange is happening... */
			printf("Unable to open src %s directory\n", src);
			goto exit;
		}

		/* Copy every single directory entry of src into the
		 * destination directory.
		 */
		while ((dp = readdir(dir))) {
			struct stat src_s;
			struct stat dest_s;

			char src_dent[PATH_MAX];
			char dest_dent[PATH_MAX];

			str_cpy(src_dent, PATH_MAX, src);
			merge_paths(src_dent, PATH_MAX, dp->d_name);

			str_cpy(dest_dent, PATH_MAX, dest_path);
			merge_paths(dest_dent, PATH_MAX, dp->d_name);

			/* Check if we are copying a directory into itself */
			stat(src_dent, &src_s);
			stat(dest_path, &dest_s);

			if (dest_s.index == src_s.index &&
			    dest_s.fs_handle == src_s.fs_handle) {
				printf("Cannot copy a directory "
				    "into itself\n");
				goto exit;
			}

			if (vb)
				printf("copy %s %s\n", src_dent, dest_dent);

			/* Recursively call do_copy() */
			r = do_copy(src_dent, dest_dent, blen, vb, recursive,
			    force, interactive);
			if (r)
				goto exit;

		}
	} else
		printf("Unable to open source file %s\n", src);

exit:
	if (dir)
		closedir(dir);
	return r;
}